Подтвердить что ты не робот

Какая разница между полиморфизмом и множественной отправкой?

... или они одно и то же? Я замечаю, что у каждого есть своя запись в Википедии: [[1]] (http://en.wikipedia.org/wiki/Polymorphism_(computer_science)) [2], но мне трудно понять, как разные понятия.

Изменить: И как Перегрузка вписывается во все это?

4b9b3361

Ответ 1

Полиморфизм - это средство, позволяющее языку/программе принимать решения во время выполнения, при вызове метода на основе типов параметров, отправленных этому методу.

Число параметров, используемых языком/временем выполнения, определяет "тип" полиморфизма, поддерживаемый языком.

Единая отправка - это тип полиморфизма, в котором используется только один параметр (получатель сообщения - this или self) для определения вызова.

Несколько диспетчеров - это тип полиморфизма, где в нескольких параметрах используется для определения способа вызова. В этом случае приемник, а также типы параметров метода используются для указания способа вызова.

Итак, вы можете сказать, что полиморфизм является общим термином, а множественная и единственная отправка - это конкретные типы полиморфизма.

Добавление: перегрузка происходит во время компиляции. Он использует информацию о типе, доступную во время компиляции, для определения типа метода вызова. Одиночная/множественная отправка происходит во время выполнения.

Пример кода:

using NUnit.Framework;

namespace SanityCheck.UnitTests.StackOverflow
{
    [TestFixture]
    public class DispatchTypes
    {
        [Test]
        public void Polymorphism()
        {
            Baz baz = new Baz();
            Foo foo = new Foo();

            // overloading - parameter type is known during compile time
            Assert.AreEqual("zap object", baz.Zap("hello"));
            Assert.AreEqual("zap foo", baz.Zap(foo));


            // virtual call - single dispatch. Baz is used.
            Zapper zapper = baz;
            Assert.AreEqual("zap object", zapper.Zap("hello"));
            Assert.AreEqual("zap foo", zapper.Zap(foo));


            // C# has doesn't support multiple dispatch so it doesn't
            // know that oFoo is actually of type Foo.
            //
            // In languages with multiple dispatch, the type of oFoo will 
            // also be used in runtime so Baz.Zap(Foo) will be called
            // instead of Baz.Zap(object)
            object oFoo = foo;
            Assert.AreEqual("zap object", zapper.Zap(oFoo));
        }

        public class Zapper
        {
            public virtual string Zap(object o) { return "generic zapper" ; }
            public virtual string Zap(Foo f) { return "generic zapper"; }
        }

        public class Baz : Zapper
        {
            public override string Zap(object o) { return "zap object"; }
            public override string Zap(Foo f) { return "zap foo"; }
        }

        public class Foo { }
    }
}

Ответ 2

При многократной диспетчеризации метод может иметь несколько переданных ему аргументов и какая реализация используется, зависит от каждого типа аргумента. Порядок оценки типов зависит от языка. В LISP он проверяет каждый тип от первого до последнего. Языки с несколькими диспетчерами используют общие функции, которые являются просто функциями декартации и не похожи на общие методы, которые используют параметры типа.

Несколько диспетчеров позволяют подтипирование полиморфизма аргументов для вызовов методов.

Одиночная отправка также допускает более ограниченный тип полиморфизма (одно имя метода для объектов, которые реализуют один и тот же интерфейс или наследуют один и тот же базовый класс). Это классический пример полиморфизма, где у вас есть методы, которые переопределяются в подклассах.

Кроме того, generics предоставляют полиморфизм параметрического типа (например, один и тот же общий интерфейс для использования с разными типами, даже если они не связаны, например List <T> - это может быть список любого типа и используется одинаково независимо).

Ответ 3

Я никогда не слышал о Multiple Dispatch раньше, но, взглянув на страницу Википедии, он очень похож на MD - это тип полиморфизма при использовании с аргументами метода.

Полиморфизм - это по сути понятие о том, что объект можно рассматривать как любой тип, который является основой. Поэтому, если у вас есть автомобиль и грузовик, их можно рассматривать как автомобиль. Это означает, что вы можете вызвать любой метод транспортного средства для одного из них.

Несколько диспетчеров выглядят одинаково, поскольку они позволяют вызывать методы с аргументами нескольких типов, однако я не вижу определенных требований в описании. Во-первых, он, как представляется, не требует общего базового типа (не то, что я мог бы представить реализацию THAT без void *), и вы можете иметь несколько объектов.

Поэтому вместо вызова метода Start() для каждого объекта в списке, который является классическим примером полиморфизма), вы можете вызвать метод StartObject (Object C), определенный в другом месте, и запрограммировать его для проверки типа аргумента во время выполнения и обрабатывайте его соответствующим образом. Разница здесь в том, что метод Start() должен быть встроен в класс, тогда как метод StartObject() может быть определен вне класса, поэтому различным объектам не нужно соответствовать интерфейсу.

Что может быть приятно, если метод Start() необходимо вызвать с разными аргументами. Возможно, Car.Start(Key carKey) против Missile.Start(int launchCode)

Но оба могут быть вызваны как StartObject (theCar) или StartObject (theMissile)

Интересная концепция...

Ответ 4

Несколько Dispatch - это своего рода полиморфизм. В Java/С#/С++ существует полиморфизм через наследование и переопределение, но это не Multiple Dispatch, основанный на 2 или более аргументах (а не только этот, как в Java/С#/С++)

Ответ 5

Несколько Dispatch более сродни перегрузке функций (как видно из Java/С++), кроме вызываемой функции зависит от типа времени выполнения аргументов, а не от их статического типа.

Ответ 6

если вы хотите концептуальный эквивалент вызова метода

(obj_1, obj_2, ..., obj_n)->method

чтобы зависеть от каждого конкретного типа в кортеже, тогда вам нужна множественная отправка. Полиморфизм соответствует случаю n = 1 и является необходимой особенностью ООП.

Ответ 7

Несколько Dispatch полагается на основе полиморфизма. Типичный полиморфизм, встречающийся в С++, С#, VB.NET и т.д., Использует единую диспетчеризацию - то есть вызываемая функция зависит только от экземпляра одного класса. Многократная отправка зависит от нескольких экземпляров класса.