درآمدی بر Inheritance (وراثت) در زبان PHP

درآمدی بر Inheritance (وراثت) در زبان PHP

نیاز به توضیح نیست که مبتکرین برنامه‌نویسی شیئ‌گرا، از اشیاء دنیای واقعی برای چنین رویکردی در برنامه‌نویسی الهام گرفته‌اند. به عبارت دیگر، همان‌طور که ما در دنیای واقعی با اشیاء سر و کار داریم، زمانی که پروژه‌ای را با اصول OOP می‌نویسیم نیز با آبجکت‌ها یا همان اشیاء درگیر هستیم و یکی دیگر از ویژگی‌هایی که مبتکرین شیئ‌گرایی از جهان واقعی الهام گرفته‌اند، مفهوم Inheritance یا «وراثت» است. همهٔ ما برخی از خصوصیات‌مان را از پدر، پدر بزرگ، دایی و … به ارث می‌بریم و آن خصیصه‌ها به عنوان بخشی از ذات ما می‌شوند. در برنامه‌نویسی شیئ‌گرا نیز چیزی تحت عنوان وراثت داریم. حال برای آن که به خوبی با مفهوم وراثت در برنامه‌نویسی به‌خصوص زبان برنامه‌نویسی PHP آشنا شویم، سعی می‌کنیم یک مثال در دنیای واقعی را به یک پروژهٔ کوچک تبدیل کنیم. 

حیوانات دارای یکسری خصوصیات هستند که مابین ایشان مشترک است مثل خوردن، خوابیدن و … اما این در حالی است که برخی حیوانات از خصوصیاتی برخوردارند که سایر حیوانات فاقد آنها هستند مثلاً مار می‌تواند نیش بزند اما گنجشک از چنین قابلیتی برخوردار نیست. در زبان انگلیسی زمانی که بخواهیم حیوانات را به صورت کلی در نظر بگیریم، می‌توانیم واژهٔ Animal را مورد استفاده قرار دهیم. از این رو، فایلی ایجاد می‌کنیم تحت عنوان Animal.php و داخل این فایل کلاسی تعریف می‌کنیم تحت عنوان Animal:


class Animal 
{
    public $name;
    function __construct($input) 
    {
        $this->name = $input;
    }

    public function eat() {
        echo "$this->name is eating";
    }
    
    public function sleep() {
        echo "$this->name is sleeping";
    }
}

در ادامه قصد داریم تا یک پراپرتی کلی برای کلاسمان تعریف کنیم؛ پس متغیری تحت عنوان name$ را داخل این کلاس می‌نویسیم. حال می‌خواهیم از یک کانستراکتور در کلاس خود استفاده کنیم تا به محض اینکه شیئی از روی این کلاس ساخته شد، دستورات داخل آن اجرا شوند (برای آشنایی بیشتر با مفهوم کانستراکتور، به مقالهٔ آشنایی با مفاهیم Constructor و Destructor در PHP به زبان ساده مراجعه نمایید).

در تفسیر کدهای فوق بایستی گفت که به محض ساخت یک آبجکت از روی کلاس Animal، متد کانستراکتور به صورت خودکار اجرا می شود و پارامتر ورودی‌اش را به متغیر name$ پاس می‌دهد؛ در ادامه ۲ متد تعریف کرده‌ایم تحت عناوین ()eat و ()sleep که به ترتیب «خوردن» و «خوابیدن» معنی می‌دهند و کاری که این متدها انجام می‌دهند این است که پارامتر ورودی متد کانستراکتور را به عبارات «is eating» و «is sleeping» ضمیمه کرده و در معرض دید کاربر قرار می‌دهند.

در این مرحله از کار، کدهای مرتبط با کلاس Animal به پایان می‌رسند. لازم به ذکر است قابلیت‌هایی که در این کلاس تعریف کردیم مابین تمامی حیوانات مشترک‌اند. حال قصد داریم تا کلاسی اختصاصی برای گربه ایجاد کنیم که نه تنها دارای خصوصیات مخصوص به خود است، بلکه کلیه خصوصیات کلاس حیوان را نیز اصطلاحاً به ارث برده است:


class Animal 
{     
    public $name;     
    function __construct($input) 
    {         
        $this->name = $input;
    }

    public function eat() {
        echo "$this->name is eating";
    }

    public function sleep() {
        echo "$this->name is sleeping";
    }
}

class Cat extends Animal
{
    public function meow() 
    {
        echo "$this->name is meowing";
    }
}

همان‌طور که در کد فوق ملاحظه می‌شود، کلاسی جدید تحت عنوان Cat ایجاد کرده‌ایم و از آنجا که می‌خواهیم این کلاس کلیهٔ خصوصیات کلاس حیوان را به ارث ببرد، از کلیدواژه‌ای تحت عنوان extends استفاده کرده سپس نام کلاسی که می‌خواهیم از آن ارث‌بری کنیم را نوشته‌ایم که در این مثال Animal است.

از این پس، کلاس گربه دارای کلیهٔ خصوصیات کلاس حیوان است که از آن جمله می‌توان به خوردن و خوابیدن اشاره کرد؛ علاوه بر این، کلاس گربه دارای یک قابلیت منحصر به خود نیز هم هست که میومیو کردن است. به عبارت دیگر، داخل کلاس Cat متدی تعریف کرده‌ایم تحت عنوان ()meow که پراپرتی name$ را به عبارت «is meowing» ضمیمه کرده و در معرض دید کاربر قرار می‌دهد.

به همین صورت کلاس دیگری تحت عنوان Dog ایجاد کرده که از کلاس Animal ارث‌بری می‌کند که دارای یکسری قابلیت منحصر به فرد همچون واق‌واق کردن می‌باشد:


class Animal 
{     
    public $name;     
    function __construct($input) 
    {         
        $this->name = $input;
    }

    public function eat() 
    {
        echo "$this->name is eating";
    }
    
    public function sleep() 
    {
        echo "$this->name is sleeping";
    }
}

class Cat extends Animal
{
    public function meow() 
    {
        echo "$this->name is meowing";
    }
}

class Dog extends Animal
{
    public function bark() 
    {
        echo "$this->name is barking";
    }
}

همان‌طور که در کد فوق ملاحظه می‌شود، متدی تحت عنوان ()bark به معنی «واق واق» ایجاد کرده و پراپرتی name$ را به عنوان خروجی این متد به علاوهٔ عبارت «is barking» در نظر گرفته‌ایم. برای اینکه خیلی پروژهٔ ما پیچیده نشود، قصد داریم تا آبجکت‌های مد نظر خود داخل همین کلاس تعریف کنیم. لذا ابتدا یک آبجکت از روی کلاس گربه ایجاد کرده و متدهای آن را فرا می‌خوانیم:


class Animal 
{     
    public $name;     
    function __construct($input) 
    {         
        $this->name = $input;
    }

    public function eat() 
    {
        echo "$this->name is eating";
    }

    public function sleep() 
    {
        echo "$this->name is sleeping";
    }
}

class Cat extends Animal
{
    public function meow() 
    {
    echo "$this->name is meowing";
    }
}

class Dog extends Animal
{
    public function bark() 
    {
        echo "$this->name is barking";
    }
}

$cat = new Cat('Makhmali');
$cat->eat();
echo '<br>';
$cat->sleep();
echo '<br>';
$cat->meow();

همان‌طور که در کد فوق ملاحظه می‌شود، یک آبجکت تحت عنوان cat$ از روی کلاس Cat ساخته‌ایم و از آنجا که کانستراکتور کلاس Animal نیاز به یک پارامتر ورودی به عنوان «نام» دارد، نامی همچون مخملی را برای گربهٔ خود در نظر گرفته‌ایم.

اینجا است که مفهوم واقعی وراثت در برنامه‌نویسی را درک خواهیم کرد. همان‌طور که در کد فوق ملاحظه می‌شود، داخل کلاس Cat ما به جزء متدی تحت عنوان ()meow، هیچ‌گونه متد دیگری نداریم اما این در حالی است که متدهایی همچون ()eat و ()sleep را در آبجکت ساخته شده از روی این کلاس فراخوانده‌ایم. علت اینکه ما اجازهٔ چنین کاری را داریم این است که کلاس گربه کلیهٔ قابلیت‌های کلاس حیوان را به ارث برده است لذا هر قابلیتی که کلاس Animal داشته باشد، کلاس Cat نیز آنها را به ارث خواهد برد. به همین منوال، می‌توان از روی کلاس سگ نیز یک آبجکت ساخت:


class Animal 
{     
    public $name;     
    function __construct($input) 
    {         
        $this->name = $input;
    }

    public function eat() 
    {
        echo "$this->name is eating";
    }

    public function sleep() 
    {
        echo "$this->name is sleeping";
    }
}

class Cat extends Animal
{
    public function meow() 
    {
        echo "$this->name is meowing";
    }
}

class Dog extends Animal
{
    public function bark() 
    {
        echo "$this->name is barking";
    }
}

$cat = new Cat('Makhmali');
$cat->eat();
echo '<br>';
$cat->sleep();
echo '<br>';
$cat->meow();
echo '<br>';
echo '<br>';
$dog = new Dog('Barfi');
$dog->eat();
echo '<br>';
$dog->sleep();
echo '<br>';
$dog->bark();

می‌بینیم که آبجکتی از روی کلاس سگ ساخته‌ایم تحت عنوان dog$ و به عنوان پارامتر ورودی نامی همچون برفی را برای آن در نظر گرفته‌ایم و این در حالی است که این کلاس هم همچون کلاس گربه، کلیهٔ خصوصیات کلاس حیوان را به ارث برده و به علاوه دارای متد دیگری تحت عنوان ()bark است. توجه داشته باشیم که آبجکت dog$ صرفاً به متدهای کلاس Animal و Dog دسترسی دارد و در صورتی که متد ()meow که به کلاس Cat اختصاص دارد را در آن مورد استفاده قرار دهیم، با ارور مواجه خواهیم شد:

 درآمدی بر Inheritance (وراثت) در زبان PHP

در یک کلام می‌توان گفت که استفاده از مفهوم وراثت در کدنویسی، می‌تواند از دوباره کاری و نوشتن کدهای تکراری به طرز قابل‌توجهی جلوگیری کند و این در حالی است که اگر بخواهیم از کدنویسی Pure PHP به سمت فریمورک‌های این زبان همچون لاراول،‌ سیمفونی، زند و غیره مهاجرت کنیم، حتماً می‌بایست با مفهوم Inheritance آشنایی داشته باشیم (چنانچه علاقمند به فراگیری گام به گام زبان برنامه‌نویسی PHP هستید، می‌توانید به دورهٔ آموزش PHP در سکان آکادمی مراجعه نمایید).