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

StackOverflow https://stackoverflow.com/questions/125050

Вопрос

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

Редактировать: И как это происходит Перегрузка вписываешься во все это?

Это было полезно?

Решение

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

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

Одиночная отправка - это тип полиморфизма, в котором используется только один параметр (получатель сообщения - 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 { }
    }
}

Другие советы

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

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

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

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

Я никогда раньше не слышал о множественной отправке, но, взглянув на страницу Википедии, становится очень похоже, что 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)

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top