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

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

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

В PHP
В PHP
В большой кодовой базе с множеством различных компонентов классы, функции и константы могут иметь одинаковые имена. Это может привести к путанице и...
Принцип подстановки Лискова
Принцип подстановки Лискова
Принцип подстановки Лискова (LSP) - это принцип объектно-ориентированного программирования, который гласит, что объекты суперкласса должны иметь...
33
0
8 016
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Ответ принят как подходящий

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

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

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

Замечательный ответ! А ++++++ СПРОСИТЕ СНОВА

raldi 24.09.2008 09:43

Спасибо! Это помогло мне собрать воедино концепции, которые я прочитал в Википедии.

John 02.03.2009 20:56

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