Honestly not strong in modern terms, but before that what you brought:
Ad hoc polymorphism
Parametric polymorphism
Called "function / method overload". What's up
Subtype polymorphism
It really is important today. What is the essence - in the comments gave a good link to the article. But it's not cool when non-living examples are given for learning: you won't see this in PHP.
But the examples that I add: I see in PHP every day, and it seems to me they will help to reveal the essence of this concept. In the database of almost every site there are users, articles, photos. For universal work with rows of the database, there is the ActiveRecord pattern, which polyformism uses most clearly. For example, there are classes that describe the rows in the database:
class User extends ActiveRecord class Article extends ActiveRecord class Photo extends ActiveRecord
ActiveRecord itself has onboard methods save() , setFromArray() , getId() . Examples of how to work with ActiveRecord :
//1 $user = new User(1234);//получение юзера с id=1234 из БД $user->first_name = 'Евпатий'; $user->save(); //2 $article = new Article(1234); $article->setFromArray($formdata); $article->save(); echo('Article '. $article->getId(). ' saved');
For example, before saving the article specifically, we want to make a trigger and reset the cache, for this we extend the behavior of the save method:
class Article extends ActiveRecord { ... public function save() { $this->resetSomeArticleCache(); return parent::save(); } }
Thus, somewhere in the code there may be a universal controller whose task is to update a certain field, which many records have:
public function upgradeModifyDateAction() { $type = $_GET['type']; $id = (int)$_GET['id']; //полиморфное получение ряда тут максимально наглядно описано, обычно это как-то Core::getRow($type, $id) if (is_subclass_of($type, 'ActiveRecord') && ($row = new $type($id)) && $row->isExists() && $row->fieldExists('modify_date') ){ $row->modify_date = date('Ymd H:i:s'); $row->save();// !! полиформизм здесь !! }else{/*ошибка*/} }
The bottom line is that the controller does not really care which ActiveRecord specifically asked to update, and if the object has “special behavior” to be updated, then it will be executed: that is, the resetSomeArticleCache method will be resetSomeArticleCache for the article in the example. At the same time, special behavior is transparent to the controller - this is the essence.
The main point is to save the programmer’s memory when using polymorphism: Imagine that there are not 3, but 100 different ActiveRecords in the system. To work with one of such objects (or a group), you don’t need to remember either the name of the table in which it is stored, or the name of the id column, you don’t need to think whether the list of objects is homogeneous before chasing it in a cycle: just remember that there is a getId() method getId() which returns id, and there is a save() method - which saves the object in the database.
As well as it is not necessary to think about the fact that "this is so, and if I update the article in the code, I also need to clean the cache", insert unnecessary if -s. Therefore, this is important - it is easier to live with polymorphism, to say that this is something special cannot be, today this concept is generally inseparable from inheritance in any modern world. languages.
Speaking about the types of polymorphism, in PHP they often use " duck polymorphism " - some consider it antipattern, and some praise it. For me, it is moderately useful:
/*например функция проверки прав $user на $object*/ public function checkRights($user, $object, $right = 'edit') { ... if (method_exists('isExtraAllowed', $object)){ if (($result = $object->isExtraAllowed($user, $right)) != self::IGNORE) return $result; } ... }
In the example, the fact is that it would be blasphemous to get the basic isExtraAllowed in ActiveRecord , since ActiveRecord does not belong to rights in principle - and we will spread a clear class to ourselves. And the need to add such a duck-polymorphic insert as isExtraAllowed occurs in real projects in my memory always (where, of course, the OOP is widely used), especially if the ACL rights system was introduced far after the start of the project.
Yes, in the example it would be possible to add an interface instead of the duck approach, calling for example IACLExtendedProvider , but firstly it will score a global list of classes and interfaces (and the programmer’s brain at the same time), secondly a programmer who is not used to interfaces will go into a stupor when it will not understand why the isExtraAllowed method added by it isExtraAllowed not work.