Полиморфизъм, поне в PHP имаме, когато имаме интерфейс, задаващ схемата на класовете, които го имплементират, и във отделните класове имаме един или повече метода, които правят различни неща според класа.
Но понеже името, и изобщо signature на такива методи е общ, се създава впечатление, че е един и същ метод, вършещ различни неща според класа си. А те реално са съвсем отделни методи.
According to the Polymorphism principle, methods in different classes that do similar things should have the same name.
Ето го примерният интерфейс:
interface Shape { public function calcArea(); }
Ако имаме клас Circle implpements Shape или Square implements Shape, или каквъвто и да е shape… то за всеки клас, методът calcArea() ще върши различна работа.
Полиморфизмът в обектно ориентираното програмиране представлява свойството на обектите от един и същи интерфейс, но с различна реализация на този интерфейс да правят различни неща.
Това важи и за абстрактните класове – общите неща са отделени в абстрактният клас, но специфичните – според конкретния случай.
Различни неща или обекти могат да имат еднакъв интерфейс или да отговарят на едно и също (по наименование) съобщение и да реагират подходящо, в зависимост от природата или типа на обекта. Това позволява много различни неща да бъдат взаимозаменими. Например, ако една птица получи съобщение „движи се“, тя ще маха с крила и ще лети. Ако един лъв получи същото съобщение, той ще тича, използвайки краката си. И двете животни отговарят на една и съща команда по начини, които са свойствени за всяко от тях. Все едно два обекта, имплементиращи общ интерфейс, имплементирайки го по свой си начин.
Три са най-разпространените форми на полиморфизъм:
Ad hoc polymorphism или още Overloading
Различна имплементация на функция, на база на това какъв тип аргументи и се подава. Още е известен като „function overloading“ или „operator overloading“. Демек, това си е точно оверлоудване на функция. Ad hoc се използва, когато имаме например функции с едно име но различни имплементации, всеки за конкретен случай, и явно затова се казва ad hoc – „специално за“, „само за“.
program Adhoc; function Add(x, y : Integer) : Integer; begin Add := x + y end; function Add(s, t : String) : String; begin Add := Concat(s, t) end; begin Writeln(Add(1, 2)); (* Prints "3" *) Writeln(Add('Hello, ', 'Mammals!')); (* Prints "Hello, Mammals!" *) end.
Subtyping
Тук се използва идеята, че чисто логически може типовете входни параметри и изходни резултати да се организират йерархично. Как програмно става това? Например, спазвайки SOLID принципа „Dependency Inversion Principle“, можем да използваме така да се каже по-общ тип, а не конкретен. Същата идея може да се реализира и с използването на абстрактен клас като тип.
Какво изобщо е „subtyping“? Помним „Liskov substitution principle“, e това е същото, но не за функции, а за типове. Демек, „родителският“ тип трябва да може да замества „детският“, бидейки негово „обобщение“. Както и „детският“ да замества „родителският“ бидейки негов „частен случай“.
Така се получава, че даден обект може да е от повече от един тип, като тези типове са йерархично организирани.
Идеята е да се даде по-широко поле на възможният тип, който може да се приема, но все пак да има някаква йерархия.