با سلام و عرض ادب،
در این قسمت به سراغ مبحث معروف Polymorphism (واژه ای یونانی به معنی «چند شکلی» یا «چند ریختی») در PHP می رویم. Polymorphism یک قرار داد نام گذاری است که به ما کمک می کند کد های منطقی و با ثبات بنویسیم تا استفاده از آن ها راحت تر شود. بر اساس قانون چند ریختی، متد هایی که در کلاس های مختلف قرار دارند اما کار های یکسان انجام می دهند باید همنام باشند.
یکی از مثال های زیبا در این زمینه مثال کلاس هایی است که نماینده ی شکل های هندسی (مانند مربع، مستطیل، مثلث، دایره و...) هستند. این اشکال فرمول های مختلفی برای محاسبه ی مساحت خود دارند اما فرمول هر کدام با دیگری متفاوت است. در چنین حالتی بر اساس قانون چند ریختی، تمام متد هایی که مساحت را حساب می کنند (بدون توجه به اینکه مساحت چه شکلی را حساب می کنند) باید نام های مساوی داشته باشند.
به طور مثال می توانیم متدی که مساحت را محاسبه می کند (مثل نام آن را ()calcArea که مخفف calculate area است، می گذاریم) صدا زده و در تک تک کلاس هایی که نماینده ی یکی از اشکال هندسی هستند، متدی قرار می دهیم که مساحت را بر اساس شکل آن محاسبه کند. در این حالت هر گاه بخواهیم مساحت شکلی را حساب کنیم، متدی با نام ()calcArea را صدا می زنیم آن هم بدون اینکه نیازی باشد تا به جزئیات فنی مربوط به محاسبه ی تک تک شکل ها توجه زیادی نشان دهیم. تنها چیزی که باید بدانیم نام متدی است که مساحت را حساب می کند.
برای پیاده سازی قانون چند ریختی یا Polymorphism در پروژه ی خود باید یا کلاس های انتزاعی را انتخاب کنیم و یا اینترفیس ها را. اگر یادتان باشد در جلسات قبل گفتیم برای اینکه بخواهیم اعضای تیم برنامه نویسی یا حتی خودتان را مجبور به استفاده از متد خاصی کنید می توانید از کلاس های انتزاعی و یا اینترفیس ها استفاده کرده و تفاوت های این دو را نیز بیان کردیم.
برای مطالعه ی این مقاله روی این لینک کلیک کنید.
همچنین برای مطالعه ی مقاله ی مربوط به کلاس های انتزاعی روی این لینک کلید کنید.
در مثال زیر اینترفیسی با نام shape (به معنی شکل) وجود دارد که به تمام کلاس هایی که از آن ارث بری دارند می گوید باید متدی با نام ()calcArea تعریف کنند.
interface Shape { public function calcArea(); }
بر همین اساس کلاس circle (به معنی دایره) اینترفیس بالا را در خود پیاده سازی کرده و بنابراین مجبور است متد ()calcArea را با فرمول مخصوص محاسبه ی مساحت دایره بنویسد. اگر از ریاضی دوران دبیرستان و راهنمایی یادتان مانده باشد مساحت دایره به شکل زیر حساب میشد:
بنابراین:
class Circle implements Shape { private $radius; public function __construct($radius) { $this -> radius = $radius; } // مساحت دایره را حساب می کند calcArea public function calcArea() { return $this -> radius * $this -> radius * pi(); } }
کلاس rectangle (به معنی مستطیل) نیز از اینترفیس shape استفاده کرده و متد ()calcArea را برای خود اما با همان نام می نویسد:
class Rectangle implements Shape { private $width; private $height; public function __construct($width, $height) { $this -> width = $width; $this -> height = $height; } // مساحت دایره را حساب می کند calcArea public function calcArea() { return $this -> width * $this -> height; } }
یادآوری: آیا یادتان هست که construct__ چه بود؟ در جلسات گذشته به طور خلاصه توضیح دادیم که setter ها به شکل زیر کار می کنند:
class Car { private $model; public function setModel($model) { $this -> model = $model; } public function getModel() { return "The car model is " . $this -> model; } }
به عبارت دیگر کار setter ها تغییر مقدار مقادیری است که روی حالت private هستند. و از طرفی گفتیم construct__ نیز به این شکل کار می کند:
class Car{ private $model; public function __construct($model) { $this -> model = $model; } }
به عبارت دیگر construct__ برای خصوصیات شما مقادیر اولیه تعریف می کند و بر همین اساس اگر از چنین کدی (کد بالا) شیء ای ساخته شود:
$car1 = new Car();
با خطای زیر مواجه خواهیم شد:
Warning: Missing argument 1 for Car::__construct()
خطا به این دلیل بود که مقدار اولیه برای شیء ساخته شده تعیین نشد. می توان به construct__ به عنوان یک متد انتزاعی منتها برای خصوصیات (property ها) نگاه کرد.
اگر کد مربوط به construct__ را نمی فهمید یا یادتان رفته است به مقاله ی «مفاهیم Setter ،Getter و Constructor» مراجعه کنید. در قسمت پایانی این مقاله توضیحات مربوط به constructor ها را پیدا خواهید کرد.
حالا می توانیم از کلاس های دایره و مستطیل یک نمونه بسازیم:
$circ = new Circle(3); $rect = new Rectangle(3,4);
بدین ترتیب تا زمانی که یک کلاس از اینترفیس shape استفاده کند، می توانیم مطمئن باشیم که تمامی اشیاء مساحت را با متد ()calcArea و به طور صحیح (چه مربع باشد، چه مستطیل باشد، چه دایره باشد و غیر آن) محاسبه می کنند.
حالا می توانیم از متد ()calcArea استفاده کنیم تا مساحت اشکال زیر را محاسبه کنیم:
echo $circ -> calcArea(); echo $rect -> calcArea();
خروجی کد ما:
مساحت دایره: 28.274333882308
مساحت مستطیل: 12
شکر خدا با اکثر مفاهیم پایه ای برنامه نویسی شیء گرا در PHP آشنا شده ایم. اگر تا اینجای راه آمده اید به شما خسته نباشید می گویم. در جلسات آینده به سراغ برخی نکته های ریز، مطالب جا مانده یا نگفته، نکات مهم برای جمع بندی و ... می رویم. سپس مباحث ارتباط با پایگاه داده به شکل شیء گرا (رابط PDO) را مطرح می کنیم. امیدوارم از این قسمت استفاده کرده باشید.
یا حق
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.