چند ریختی
چند ریختی (Polymorphism)، به کلاسهایی که در یک سلسله مراتب وراثتی مشابه هستند، اجازه تغییر شکل و سازگاری مناسب میدهد و همچنین به برنامه نویس این امکان را میدهد که به جای ایجاد برنامههای خاص، برنامههای کلی و عمومیتری ایجاد کند.. به عنوان مثال در دنیای واقعی همه حیوانات غذا میخورند، اما روشهای غذا خوردن آنها متفاوت است. در یک برنامه برای مثال، یک کلاس به نام Animal ایجاد میکنید. بعد از ایجاد این کلاس میتوانید آن را چند ریخت (تبدیل) به کلاس Bird کنید و متد Fly() را فراخوانی کنید. به مثالی در باره چند ریختی توجه کنید :
1:<?php 2: 3: class Animal 4: { 5: public function Eat() 6: { 7: echo 'The animal ate!' .'<br/>'; 8: } 9: } 10: 11: class Dog extends Animal 12: { 13: function Eat() 14: { 15: echo 'The dog ate!' .'<br/>'; 16: } 17: } 18: 19: 20: class Bird extends Animal 21: { 22: function Eat() 23: { 24: echo 'The bird ate!' .'<br/>'; 25: } 26: } 27: 28: class Fish extends Animal 29: { 30: function Eat() 31: { 32: echo 'The fish ate!' .'<br/>'; 33: } 34: } 35: 36: 37: $myDog = new Dog(); 38: $myBird = new Bird(); 39: $myFish = new Fish(); 40: $myAnimal = new Animal(); 41: 42: $myAnimal ->Eat(); 43: 44: $myAnimal = $myDog; 45: $myAnimal ->Eat(); 46: 47: $myAnimal = $myBird; 48: $myAnimal ->Eat(); 49: 50: $myAnimal = $myFish; 51: $myAnimal ->Eat(); 52: 53:?>
The animal ate! The dog ate! The bird ate! The fish ate!
همانطور که مشاهده میکنید 4 کلاس مختلف تعریف کردهایم. Animal کلاس پایه است و سه کلاس دیگر از آن مشتق میشوند. هر کلاس متد Eat() مربوط به خود را دارد. نمونهای از هر کلاس ایجاد کردهایم (40-37). حال متد Eat() را به وسیله نمونه ایجاد شده از کلاس Animal به صورت زیر فراخوانی میکنیم :
$myAnimal = new Animal();
$myAnimal ->Eat();
در مرحله بعد چندریختی روی میدهد. همانطور که در مثال بالا مشاهده میکنید، شیء Dog را برابر نمونه ایجاد شده از کلاس Animal قرار میدهیم (خط 44) و متد Eat() را بار دیگر فراخوانی میکنیم. حال با وجود اینکه ما از نمونه کلاس Animal استفاده کردهایم ولی متد Eat() کلاس Dog فراخوانی میشود. این به دلیل تأثیر چند ریختی است.
سپس دو شیء دیگر (Bird و Fish) را برابر نمونه ایجاد شده از کلاس Animal قرار میدهیم و متد Eat() مربوط به هر یک را فراخوانی میکنیم. (خطوط 51-47) به این نکته توجه کنید که وقتی در مثال بالا اشیاء را برابر نمونه کلاس Animal قرار میدهیم ازعمل Cast استفاده نکردهایم چون این کار (cast) وقتی که بخواهیم یک شیء از کلاس مشتق (مثلاً Dog) را در شیی از کلاس پایه (Animal) ذخیره کنیم لازم نیست.