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

Например, все животные могут подать голос, у всех есть метод Voice, но для каждого конкретного вида животных голос звучит по своему.

Самое короткое определение полиморфизму дал Бьерн Страуструп и оно звучит так:
Один интерфейс, множество реализаций.

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

Add hoc полиморфизм — это полиморфизм, основанный на различении типов. Для различных типов аргументов используется разный код функции.

Один классический пример — это перегрузка (overloading) метода:

				
					class C
{
    public void f(int x) { Console.WriteLine("C.f(int)"); }
    public void f(string x) { Console.WriteLine("C.f(string)"); }
}
				
			

Здесь имя f привязано к двум различным методам, и компилятор выбирает тот или иной метод в зависимости от типа аргумента. Это пример статического ad hoc-полиморфизма: типы должны быть известны на этапе компиляции, и компилятор точно знает, который из методов будет выполнен.

Другой пример ad hoc-полиморфизма — это переопределение (overriding) виртуального метода:

				
					class B
{
    public virtual void f(int x) { Console.WriteLine("B.f(int)"); }
}

class D : B
{
    public override void f(int x) { Console.WriteLine("D.f(int)"); }
}
				
			

Здесь также происходит различение по типам, но на этот раз — по типу неявного нулевого аргумента this. Выбор переопределённого метода откладывается на момент выполнения; на момент компиляции компилятор точно не знает, какой из группы переопределённых методов будет выполнен. Это пример динамического ad hoc-полиморфизма.

Кроме того, есть ещё понятие параметрического полиморфизма: это ситуация, когда один и тот же метод работает с аргументами различных типов одинаково, не зависимо от их точного типа. Тривиальный пример для языков с наследованием (например, C#) — функция, работающая с объектом некоторого класса C, часто может без изменений работать с объектом порождённого от C класса (этот вид полиморфизма часто называют полиморфизм включения). Менее тривиальный пример — generic-методы, которые могут, в зависимости от generic-параметра, работать с разными типами объектов. Пример:

				
					class Enumerable
{
    public T First(this IEnumerable<T> seq)
    {
        using (IEnumerator<T> en = seq.GetEnumerator())
        {
            if (!en.MoveNext())
                throw new InvalidOperationException();
            return en.Current;
        }
    }
}
				
			

Ad-Hock Полиморфизм это

  • Классический (Принудительный) полиморфизм т. е. Возможность динамической подмены типов (объектов) во время выполнения программы, но без второй формы Инкапсуляции т. е. без сокрытия реализации (Когда вы в классическом полиморфизме делаете upcast то происходит сокрытие свойств и методов из производного типа).

или

  • Возможность обращаться с объектами у которых одинаковый интерфейс взаимодействия одинаковым образом

Пример:

				
					class A{public void Method(){Console.WriteLine("A");}}

class B{public void Method(){Console.WriteLine("B");}}

class C{public void Method(){Console.WriteLine("C");}}
				
			

У этих классов нету базового класса но у них одинаковый интерфейс взаимодействия.

Ad hoc полиморфизм или (Полиморфизм для конкретного случая) позволяет обращаться схожим образом к объектам, не связанным классическим наследованием.

Пример:

				
					// данный интерфейс создан для создания своего рода базового типа 
// для классов А, B, и C у которых нету такового.

interface IInterface
{
    void Method();
}
// в данном случае мы создаем новые классы обертки со схожими интерфейсами 
// и с базовым типом
class MyA : A, IInterface { }
class MyB : B, IInterface { }
class MyC : C, IInterface { }

class Program
{
    static void Main()
    {
        // тем самым мы работаем с классами как будто у них был базовый тип
        // но  без сокрытия реализации
        IInterface instance = new MyA();
        instance.Method();
        instance = new MyB();
        instance.Method();
        instance = new MyC();
        instance.Method();
    }
}
				
			
Ad hoc Полиморфизм в C#

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.