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

... или это одно и то же? Я заметил, что у каждого есть своя собственная запись в Википедии: Полиморфизм, Многократная рассылка, но у меня возникают проблемы с различием понятий.

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

7 ответов

Решение

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

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

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

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

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

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

Образец кода:

using NUnit.Framework;

namespace SanityCheck.UnitTests.Stackru
{
    [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 { }
    }
}

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

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

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

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

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

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

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

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

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

Но оба можно назвать StartObject(theCar) или же StartObject(theMissile)

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

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

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

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

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

Multiple Dispatch - это разновидность полиморфизма. В Java/C#/C++ есть полиморфизм через наследование и переопределение, но это не множественная диспетчеризация, которая основана на двух или более аргументах (не только thisкак в Java/C#/C++)

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

Другие вопросы по тегам