2008-09-24 18 views
28

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

Edit:.? И как Overloading вписываться все это

ответ

38

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

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

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

Это очень хороший ответ - если вы добавите короткие фрагменты кода, чтобы показать пример каждого из них, я думаю, что я буду принимать его в качестве ответа. – raldi 2008-09-24 04:13:58

1

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

1

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

0

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

2

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

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

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

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

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

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

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

1

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

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

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

3

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

Несколько отправлений допускают для аргументов subtyping polymorphism аргументов.

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

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