وراثت یا inheritance در شی گرایی

تاریخ: 30 فروردین 1400

یکی از ویژگی های مهم برنامه نویسی شی گرا، وراثت یا inheritance می باشد. وراثت به این معناست که یک کلاس می تواند از یک کلاس دیگر اقتباس شود. در اینصورت دسترسی به مشخصات کلاس والد، در کلاس فرزند نیز امکان پذیر خواهد بود.

مفهوم وراثت یا inheritance در شی گرایی

مفهوم وراثت در شی گرایی، امکان استفاده از subclass ها از class والد را ایجاد می کند.

در واقع مفهوم وراثت، کلاس های والد و فرزند ایجاد می کند. طوری که کلاس های فرزند یا subclass ها می توانند از مشخصات کلاس والد استفاده کنند.

برای تعریف یک subclass از یک class از کیورد extends استفاده می شود:

class Foo {}
class Bar extends Foo {}
$object = new Bar();

در واقع استفاده از وراثت زمانی انجام می شود که چند کلاس موجود، یک یا چند متد یا ویژگی تکراری داشته باشند.

در اینصورت یک کلاس والد در نظر می گیریم و بقیه کلاس ها را از این کلاس اقتباس می کنیم تا در همه ی کلاس های فرزند، به ویژگی ها یا متدهای کلاس والد دسترسی داشته باشیم.

در واقع کلاس والد نقطه ی اشتراک همه ی subclass ها می باشد و اطلاعات آن برای همه ی subclass ها قابل دسترسی است.

کلاس فرزند طوری است که انگار ادامه ی کلاس والد است.

 

ساختن آبجکت از subclass قبل از تعریف آن

اگر بخواهیم قبل از اینکه subclass تعریف شود، از آن آبجکت بسازیم، حتما باید کلاس والد از قبل تعریف شده باشد:

//false
$object = new Product; // error Class "Product" not found
class Product extends User {
    public function __construct() {
        echo 123;
    }
}
class User {}

//true
class User2 {}
$object = new Product2; //output: 123
class Product2 extends User {
    public function __construct() {
        echo 123;
    }
}

 

در مثال بالا از متد construct__ استفاده کردیم که به صورت خودکار هنگام تعریف آبجکت ران می شود.

 

دسترسی به متغیرهای کلاس والد در subclass

در شی فرزند، استفاده از متغیرهای کلاس والد امکان پذیر می باشد. برای این کار از کیورد this$ استفاده می کنیم:

class Foo {
    public $var = 'Biawp.ir';
}
class Bar extends Foo {
    function show_appName() {
        return $this->var;
    }
}
$object = new Bar();
echo $object->show_appName(); //output: Biawp.ir

مشاهده کردید که امکان استفاده از متغیر کلاس والد در subclass به راحتی امکان پذیر است.

 

دسترسی به متدهای کلاس والد در subclass

در شی فرزند، استفاده از متدهای کلاس والد امکان پذیر می باشد. برای این کار از کیورد this$ استفاده می کنیم:

class Foo {
    public $var = 'Biawp.ir';
    function show_appName() {
        return $this->var;
    }
}
class Bar extends Foo {
    function subclass_method() {
        return $this->show_appName();
    }
}
$object = new Bar();
echo $object->subclass_method(); //output: Biawp.ir

مشاهده کردید که امکان استفاده از متد کلاس والد در subclass به راحتی امکان پذیر است.

 

دسترسی به ثابت های کلاس والد در subclass

در شی فرزند، استفاده از ثابت های کلاس والد امکان پذیر می باشد. برای این کار از کیورد parent یا self و یک double clone استفاده می کنیم:

class Foo {
    const APP = 'Biawp.ir';
}
class Bar extends Foo {
    function subclass_method() {
        return parent::APP;
    }
}
$object = new Bar();
echo $object->subclass_method(); //output: Biawp.ir

مشاهده کردید که امکان استفاده از ثابت های کلاس والد در subclass به راحتی امکان پذیر است.

دسترسی به متغیرها، متدها و ثابت های یک کلاس والد در subclass، به همان صورتی که در کلاس والد وجود دارد، می باشد. یعنی برای متغیرها و متدها از کیورد this$ و برای ثابت ها از کیورد self یا parent استفاده می کنیم.

 

سطوح دسترسی متغیرها، متدها و ثابت ها در کلاس

متغیرها، متدها و ثابت های یک کلاس، می توانند یکی از سطح دسترسی های protected ،private ،public را دارا باشند. این سطح دسترسی باید در هنگام تعریف آنها مشخص شود:

class Biawp {
    public $name;
    private $age;
    protected $height;
    public const NAME;
    private const AGE;
    protected const HEIGHT;
    public show_name() {}
    private show_age() {}
    protected show_height() {}
}

 

سطح دسترسی public متغیرها، متدها و ثابت ها

اگر بخواهیم متد، متغیر یا ثابت ما در خارج از کلاس و توسط آبجکت، قابل دسترسی و تغییر باشد، از کیورد public استفاده می کنیم:

class Biawp {
    public const COLOR = '#000fff';
    public $name = 'Biawp.ir';
    public function show_name() {
        return $this->name;
    }
}
$object = new Biawp();
echo $object->name; //output: Biawp.ir
echo $object->show_name(); //output: Biawp.ir

$object->name = 'Www.Biawp.ir';
echo $object->show_name(); //output: Www.Biawp.ir

echo $object::COLOR; //output: #000fff

 

نکته: متدها و ثابت ها به صورت پیشفرض دارای سطح دسترسی public می باشند. لذا نیاوردن آنها مشکلی ایجاد نمی کند ولی برای متغیرها حتما باید بیاوریم.

سطح دسترسی private متغیرها، متدها و ثابت ها

اگر متد، متغیر یا ثابت ما دارای سطح دسترسی private باشد، فقط درون کلاس قابل استفاده است. نه خارج از کلاس و نه در subclass ها.

استفاده از متغیر private درون کلاس:

class Biawp {
    private $name = 'Biawp.ir';
    function show_name() {
        return $this->name;
    }
}
$object = new Biawp();
echo $object->show_name(); //output: Biawp.ir

 

استفاده از متد private درون کلاس:

class Biawp {
    private $name = 'Biawp.ir';
    function show_name() {
        return $this->show_name_private();
    }
    private function show_name_private (){
        return $this->name;
    }
}
$object = new Biawp();
echo $object->show_name(); //output: Biawp.ir

 

استفاده از ثابت private درون کلاس:

class Biawp {
    private const COLOR = '#000fff';
    function show_name () {
        return self::COLOR;
    }
}
$object = new Biawp();
echo $object->show_name(); //output: #000fff

 

استفاده غیر مجاز از متدها، متغیرها و ثابت های private در خارج از کلاس:

class Biawp {
    private $name = 'Biawp.ir';
    private const COLOR = '#fff';
    private function show_name_private() {
        return $this->name;
    }
    public function show_name() {
        return $this->show_name_private();
    }
}
$object = new Biawp();
echo $object->name; //error - Cannot access private property
echo $object->show_name_private(); //error - Call to private method
$object->name = 'Www.Biawp.ir'; //error - Cannot access private property
echo $object::COLOR; //error - Cannot access private constant

 

استفاده غیر مجاز از متدها، متغیرها و ثابت های private در subclass:

class Biawp {
    private $name = 'Biawp.ir';
    private const COLOR = '#fff';
    private function show_name_private() {
        return $this->name;
    }
    public function show_name() {
        return $this->show_name_private();
    }
}

class Wp extends Biawp {
    function show_name_wp() {
        return $this->name;
    }
    function show_name_private_wp() {
        return $this->show_name_private();
    }
    function use_color_constant() {
        return parent::COLOR;
    }
}

$object = new Wp;
echo $object->show_name_wp(); //error - Undefined property
echo $object->show_name_private_wp(); //error - Call to private method
echo $object->use_color_constant(); // error - Undefined constant

 

سطح دسترسی protected متدها، متغیرها و ثابت ها

اگر متد، متغیر یا ثابت ما دارای سطح دسترسی protected باشد، فقط درون کلاس و همچنین subclass قابل استفاده است. نه خارج از کلاس.

استفاده از متغیر protected درون کلاس:

class Biawp {
    protected $name = 'Biawp.ir';
    function show_name() {
        return $this->name;
    }
}
$object = new Biawp();
echo $object->show_name(); //output: Biawp.ir

 

استفاده از متد protected درون کلاس:

class Biawp {
    protected $name = 'Biawp.ir';
    function show_name() {
        return $this->show_name_private();
    }
    protected function show_name_private (){
        return $this->name;
    }
}
$object = new Biawp();
echo $object->show_name(); //output: Biawp.ir

 

استفاده از ثابت protected درون کلاس:

class Biawp {
    protected const COLOR = '#000fff';
    function show_name () {
        return self::COLOR;
    }
}
$object = new Biawp();
echo $object->show_name(); //output: #000fff

 

استفاده از متغیر protected درون subclass:

class Biawp {
    protected $name = 'Biawp.ir';
}
class Wp extends Biawp {
    function show_name_wp() {
        return $this->name;
    }
}
$object = new Wp;
echo $object->show_name_wp(); //output: Biawp.ir

 

استفاده از متد protected درون subclass:

class Biawp {
    protected $name = 'Biawp.ir';
    protected function show_name() {
        return $this->name;
    }
}
class Wp extends Biawp {
    function show_name_wp() {
        return $this->show_name();
    }
}
$object = new Wp;
echo $object->show_name_wp(); //output: Biawp.ir

 

استفاده از ثابت protected درون subclass:

class Biawp {
    protected const COLOR = '#000fff';
}
class Wp extends Biawp {
    function show_name_wp() {
        return parent::COLOR;
    }
}
$object = new Wp;
echo $object->show_name_wp(); //output: Biawp.ir

 

استفاده غیرمجاز از متدها، متغیرها و ثابت های protected در خارج از کلاس:

class Biawp {
    protected $name = 'Biawp.ir';
    protected const COLOR = '#fff';
    protected function show_name_private() {
        return $this->name;
    }
    public function show_name() {
        return $this->show_name_private();
    }
}
$object = new Biawp();
echo $object->name; //error - Cannot access protected property
echo $object->show_name_private(); //error - Call to protected method
$object->name = 'Www.Biawp.ir'; //error - Cannot access protected property
echo $object::COLOR; //error - Cannot access protected constant

 

subclass ها به متغیرها، متدها و ثابت های public و protected کلاس والد دسترسی دارند.

 

وراثت چندسطحی در شی گرایی

در مفهوم وراثت می توانیم چند سطح subclass را اجرا نماییم. نحوه استفاده از مشخصات کلاس های والد در subclass خود به همان صورت بالا می باشد:

class User {
    public $name = 'Biawp.ir';
}
class Product extends User {}
class Discount extends Product {}

$object = new Discount;
echo $object->name; //output: Biawp.ir

 

 

دیدگاهتان را بنویسید