در آموزش آشنایی با مفهوم وراثت در زبان PHP به بررسی چگونگی ارثبری یک کلاس از کلاسی دیگر پرداختیم و دیدیم که به چه شکل میتوان به کلیهٔ خصوصیات کلاس والد در کلاس/کلاسهای فرزند دسترسی یافت. در عین حال ذکر این نکته ضروری است که در مبحث شیئگرایی گاهی اوقات با موقعیتهایی روبهرو میشویم که تمایلی نداریم تا این اجازه را به کلاس فرزند دهیم تا بتواند متدهای موجود در کلاس والد را اُورراید نماید و یا اساساً مواقعی نیز داریم که اصلاً نمیخواهیم تا اجازه دهیم سایر کلاسها از کلاس والد ارثبری کنند که در چنین مواقعی میباید با کاربردهای کیورد final
آشنا بود.
به منظور روشنتر شدن کاربردهای این دستور، داخل پوشهٔ oop
پروژهای تحت عنوان final-keyword
ساخته و ساختاری که تاکنون مورد استفاده قرار دادهایم را داخل آن ایجاد میکرده سپس فایلی تحت عنوان User.php
ساخته و آن را به صورت زیر تکمیل میکنیم:
<?php
namespace SokanAcademy;
class User
{
public function doSomething()
{
return 'This method is to do something.';
}
}
از این پس، کلاس User
را به عنوان کلاس اصطلاحاً Parent (والد) تلقی کرده سپس کلاس دیگری تحت عنوان Author
ساخته به طوری که نقش کلاس Child (فرزند) را بازی خواهد کرد. برای این منظور، داخل پوشهٔ classes
فایلی به نام Author.php
ساخته و آن را به صورت زیر تکمیل میکنیم:
<?php
namespace SokanAcademy;
class Author extends User
{
}
با استفاده از کیورد extends
دستور دادهایم تا کلاس Author
کلیهٔ خصوصیاتش را از کلاس User
به ارث ببرد به طوری که از این پس به متدی تحت عنوان ()doSomething
در داخل کلاس Author
دسترسی خواهیم داشت. به منظور تست این کلاس، وارد فایل index.php
شده و آن را به صورت زیر تکمیل میکنیم:
<?php
ini_set('display_errors', '1');
require_once 'vendor/autoload.php';
$obj = new SokanAcademy\Author();
echo $obj->doSomething();
میبینیم که آبجکتی از روی کلاس Author
ساختهایم تحت عنوان obj$
سپس متد ()doSomething
را به آن منتسب نمودهایم و در نهایت هم خروجی این متد را چاپ کردهایم به طوری که داریم:
/var/www/oop/final-keyword$ php index.php
This method is to do something.
پیش از این گفتیم که یکی از قابلیتهای شیئگرایی مفهومی است تحت عنوان Overriding که به موجب آن میتوان متدها و پراپرتیهای قرارگرفته داخل کلاس والد را در کلاس فرزند بازنویسی کرد. به طور مثال داریم:
<?php
namespace SokanAcademy;
class Author extends User
{
public function doSomething()
{
return 'This method is to do something in Author class.';
}
}
میبینیم که دقیقاً متدی با همان نامی که داخل کلاس User
نوشته بودیم را مجدد نوشته و محتوای داخل آن را تغییر دادهایم به طوری که اگر مجدد فایل index.php
را اجرا کنیم، به عنوان خروجی خواهیم داشت:
/var/www/oop/final-keyword$ php index.php
This method is to do something in Author class.
حال در ادامه قصد داریم تا با کاربرد کلیدواژهٔ final
در ارتباط با متدها آشنا شویم به طوری که کلاس User
را به صورت زیر تغییر میدهیم:
<?php
namespace SokanAcademy;
class User
{
final public function doSomething()
{
return 'This method is to do something.';
}
}
همانطور که میبینیم، پیش از کلیدواژهٔ public
از دستور final
استفاده کردهایم. اکنون اگر مجدد فایل index.php
را اجرا کنیم، در خروجی خواهیم داشت:
/var/www/oop/final-keyword$ php index.php
PHP Fatal error: Cannot override final method SokanAcademy\User::doSomething() in /var/www/oop/final-keyword/classes/Author.php on line 4
با اروری مواجه شدهایم که محتوایش حاکی از آن است که ما اجازهٔ اُورراید کردن متدی که از جنس final
است را نداریم. به عبارتی، میتوان گفت که کاربرد این متد در مواقعی است که قصد داریم اجازهٔ اُورراید کردن برخی متدهای کلاس والد را به کلاس فرزند ندهیم.
همچنین کیورد final
در ارتباط با تعریف کلاسها نیز کاربرد دارد که برای درک بهتر این موضوع، کلاس User
را به صورت زیر تغییر میدهیم:
<?php
namespace SokanAcademy;
final class User
{
public function doSomething()
{
return 'This method is to do something.';
}
}
ابتدا متد ()doSomething
را به حالت قبل بازگردانده و در عوض از کیورد final
قبل از کیورد class
استفاده کردهایم. ابتدا فایل index.php
را یک بار دیگر اجرا کرده سپس به بررسی عملکرد این کلیدواژهٔ در حین ساخت کلاس خواهیم پرداخت:
/var/www/oop/final-keyword$ php index.php
PHP Fatal error: Class SokanAcademy\Author may not inherit from final class (SokanAcademy\User) in /var/www/oop/final-keyword/classes/Author.php on line 4
همانطور که ملاحظه میشود، با اروری مواجه شدهایم که متن آن نشان میدهد کلاس Author
اجازهٔ ارثبری از کلاسی از جنس final
تحت عنوان User
را ندارد. به عبارتی، میتوان گفت کاربرد کلاسهایی از جنس final
در مواقعی است که قصد داریم ارثبری از کلاس مذکور را به دلایلی خاص محدود کنیم.