В чем разница между полиморфизмом и множественной отправкой?
-
02-07-2019 - |
Вопрос
... или это одно и то же?Я заметил, что у каждого из них есть своя запись в Википедии: Полиморфизм, Множественная отправка, но мне трудно понять, чем отличаются эти концепции.
Редактировать: И как это происходит Перегрузка вписываешься во все это?
Решение
Полиморфизм - это средство, которое позволяет языку / программе принимать решения во время выполнения о том, какой метод вызывать, на основе типов параметров, отправляемых этому методу.
Количество параметров, используемых языком / средой выполнения, определяет "тип" полиморфизма, поддерживаемого языком.
Одиночная отправка - это тип полиморфизма, в котором используется только один параметр (получатель сообщения - 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 и др...использует единую отправку , т. е.вызываемая функция зависит только от одного экземпляра класса.Множественная отправка зависит от нескольких экземпляров класса.