یکی از مزیت های اصلی برنامه نویسی شی گرا، کاهش تکرار در کدها با قابلیت ارث بری (inheritance) است.
تکرار کد زمانی اتفاق می افتد که برنامه نویس کد مشابه را بیشتر از یکبار می نویسد، که این مشکل را ارث بری حل کرد.
در ارث بری، یک کلاس مادر (parent) با متدها و خواص خود را داریم و یک کلاس یا کلاس های فرزند (child) داریم که می توانند از کدهای مادر استفاده کنند.
با استفاده از ارث بری، می توانیم تکه کدهایی بنویسیم که فقط یکبار در کلاس مادر بنویسم و بارها آنرا بنابر نیاز داخل کلاس های فرزند استفاده کنیم.
چطور یک کلاس، کدهای کلاس دیگر را ارث می برد؟
برای تعریف یک کلاس که کدها را از کلاس دیگر ارث می بری، از کلمه کلیدی extends
استفاده می کنیم :
1 2 3 4 5 6 7 |
class Parent { // The parent’s class code } class Child extends Parent { // The child can use the parent's class code } |
کلاس فرزند می تواند از تمام متدها و خواص (غیر پرایوت) کلاس مادر که ارث بری شده استفاده کند.
این کار به ما اجازه نوشتن یکباره کد و بعد استفاده از آن در هر دوه کلاس مادر و فرزند را می دهد.
در مثال پایین، کلاس SportsCar
از کلاس Car
ارث بری می کند، بنابراین به تمام متدها و خواص غیر پرایوت کلاس Car
دسترسی دارد.
این کار به به ما اجازه نوشتن یکباره متدها پابلیک setModel()
و hello()
داخل کلاس مادر را می دهد و بعد می توانیم در هر دو کلاس مادر و فرزند استفاده کنیم.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
//The parent class class Car { // Private property inside the class private $model; //Public setter method public function setModel($model) { $this -> model = $model; } public function hello() { return "beep! I am a <i>" . $this -> model . "</i> "; } } //The child class inherits the code from the parent class class SportsCar extends Car { //No code in the child class } //Create an instance from the child class $sportsCar1 = new SportsCar(); // Set the value of the class’ property. // For this aim, we use a method that we created in the parent $sportsCar1 -> setModel('Mercedes Benz'); //Use another method that the child class inherited from the parent class echo $sportsCar1 -> hello(); |
خروجی :
چطور یک کلاس فرزند می تواند متدها و خواص خود را داشته باشد؟
همانطور که کلاس فرزند می تواند متدها و خواص مختص به خود را داشته باشد، کلاس مادر هم می تواند.
به هر حال، زمانی که یک کلاس فرزند از کدهای کلاس مادر ارث بری شده استفاده می کند، کلاس مادر اجازه استفاده از کدهای کلاس فرزند را ندارد.
در مثال زیر، خاصیت $style
و متد driveItWithStyle()
را به کلاس فرزند اضافه کردیم:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
// The parent class has its properties and methods class Car { //A private property or method can be used only by the parent. private $model; // Public methods and properties can be used by both the parent and the child classes. public function setModel($model) { $this -> model = $model; } public function getModel() { return $this -> model; } } //The child class can use the code it inherited from the parent class, // and it can also have its own code class SportsCar extends Car{ private $style = 'fast and furious'; public function driveItWithStyle() { return 'Drive a ' . $this -> getModel() . ' <i>' . $this -> style . '</i>'; } } //create an instance from the child class $sportsCar1 = new SportsCar(); // Use a method that the child class inherited from the parent class $sportsCar1 -> setModel('Ferrari'); // Use a method that was added to the child class echo $sportsCar1 -> driveItWithStyle(); |
خروجی:
سطح دسترسی protected
زمانی که یک متد یا خاصیت را به عنوان protected
تعریف می کنیم، می توانیم از هر دو کلاس مادر و فرزند به آن دسترسی داشته باشیم.
در آموزش قبلی، یاد گرفتیم که متد یا خاصیت با سطح دسترسی public
می تواند داخل یا خارج از کلاس قابل دسترس باشد. همچنین متد یا خاصیت های private
فقط داخل خود کلاس قابل دسترس هستند.
در این بخش از آموزش شی گرایی، با سطح دسترسی سوم protected آشنا می شویم که امکان استفاده کدها داخل کلاس فرزند را می دهد.
اولین مثال ما یک خاصیت $model
را بصورت private
در کلاس مادر تعریف و سعی می کنیم در کلاس فرزند به آن دسترسی داشته باشیم.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
// The parent class class Car { //The $model property is private, thus it can be accessed // only from inside the class private $model; //Public setter method public function setModel($model) { $this -> model = $model; } } // The child class class SportsCar extends Car{ //Tries to get a private property that belongs to the parent public function hello() { return "beep! I am a <i>" . $this -> model . "</i> "; } } //Create an instance from the child class $sportsCar1 = new SportsCar(); //Set the class model name $sportsCar1 -> setModel('Mercedes Benz'); //Get the class model name echo $sportsCar1 -> hello(); |
خروجی:
Notice: Undefined property: SportsCar::$model
ما یک خطا دریافت کردیم چرا که متد hello()
در کلاس فرزند قصد دارد به خاصیت پرایوت $model
که متعلق به کلاس مادر است دسترسی پیدا کند.
می توانیم این شکل را با تعریف کردن $model
بصورت protected
حل کنیم (به جای private
)
چرا که متدها یا خواصی که بصورت protected
تعریف می شوند می توانند در هر دو کلاس مادر و فرزند قابل دسترس باشند.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// The parent class class Car { //The $model property is now protected, so it can be accessed // from within the class and its child classes protected $model; //Public setter method public function setModel($model) { $this -> model = $model; } } // The child class class SportsCar extends Car { //Has no problem to get a protected property that belongs to the parent public function hello() { return "beep! I am a <i>" . $this -> model . "</i> "; } } //Create an instance from the child class $sportsCar1 = new SportsCar(); //Set the class model name $sportsCar1 -> setModel('Mercedes Benz'); //Get the class model name echo $sportsCar1 -> hello(); |
خروجی :
beep! I am a Mercedes Benz
حالا کار کرد، چرا که با سطح دسترسی protected
می توانیم از کلاس فرزند به کدهای کلاس مادر دسترسی داشته باشیم.
چطور خواص و متدهای کلاس مادر را در کلاس فرزند override کنیم؟
همانطور که کلاس فرزند می تواند متد و خواص خود را داشته باشد، می تواند متد و خواص کلاس فرزند را بازنویسی (override) کند.
زمانی که متد و خواص کلاس را override می کنیم، باید همان را داخل کلاس فرزند دوباره بنویسیم ولی اینبار با مقادیر یا کدهای متفاوت.
در مثال پایین، ما یک متد hello()
در کلاس مادر ساهتیم که مقدار “beep” را برگشت می دهد و این متد را در کلاس فرزند بازنویسی می کنیم تا مقدار Hallo را برگشت دهد.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// The parent class has hello method that returns "beep". class Car { public function hello() { return "beep"; } } //The child class has hello method that returns "Halllo" class SportsCar extends Car { public function hello() { return "Hallo"; } } //Create a new object $sportsCar1 = new SportsCar(); //Get the result of the hello method echo $sportsCar1 -> hello(); |
خروجی :
Hallo
چطور از override شدن متدهای کلاس فرزند جلوگیری کنیم؟
برای جلوگیری از بازنویسی متدهای کلاس مادر، می توانیم کلیدواژه final
را به متدهای مادر بدیم.
در مثال پایین، متد hello()
را در کلاس مادر به عنوان final
تعریف کردیم، اما با این حال در این مثال سعی می کنیم که در کلاس فرزند آن را بازنویسی کنیم:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// The parent class has hello method that returns "beep". class Car { final public function hello() { return "beep"; } } //The child class has hello method that tries to override the hello method in the parent class SportsCar extends Car { public function hello() { return "Hallo"; } } //Create a new object $sportsCar1 = new SportsCar(); //Get the result of the hello method echo $sportsCar1 -> hello(); |
خروجی :
Fatal error: Cannot override final method Car::hello()
از آنجا که متد hello
را بصورت final
در کلاس مادر تعریف کردیم، پس نمی توان آن را در کلاس فرزند بازنویسی (override) کرد.
جمع بندی
در این بخش از آموزش شی گرایی در PHP ، با مفهوم ارث بری آشنا شدیم که به ما اجازه می داد که از کدهای کلاس مادر در کلاس های دیگر استفاده کنیم.
ارث بری به ما اجازه می دهد که بدون تکرار کد، بارها از آن استفاده کنیم و حجم را کم و خوانایی کدها را افزایش میدهد.
در آموزش بعدی، با کلاس و متدهای abstract
آشنا می شویم، که این کلاس ها قابلیت ساختن شی از آن را ندارند و متدهای آن می تواند بدون بدنه کد باشند.
سلام من یک سایت با زبان php دارم میخوام بکار ساده انجام بدم لطفاً راهنمایی ام کنید ، من یک فرم دارم که حاوی یک فیلد است بنام کد فعالسازی ، مشتری باید کد فعالسازی و توی این فیلد وارد کنه و ارسال کنه بعد از ارسال این کد توی دیتابیس ذخیره میشه و من همه ی این کد فعالسازی های ارسال شده و بر اساس تاریخ ارسال مرتب میکنم و در پنل مدیریت همه رو نشون میدم میخوام کاری کنم که کاربر جایگاه خودشو توی صف ببینه ؟ یعنی اگر ۵ نفر کد فعالسازی و فرستادن اونی که نفر آخر هست ببینه که نفر پنجم در صف هست و چهار نفر قبل از اون کد و ثبت کردن ، لطفاً اگه اطلاع دارید کدشو برام بنویسید
سلام. بعد ثبت کد کاربر تو دیتابیس براش یه سشن یا کوکی هم ست کنید که بعد از روی اون در صفحه ای که میخواید صف رو نشون بدید ایدی ردیف رو از کوکی یا سشن میخونید و تو دیتابیس کویری میزنید و نشون میدید
سلام من یک سایت ساده دارم که با پی اچ پی وصل شده به دیتابیس و بعد اطلاعات یک جدول و میگیره و در سایتم به کاربر نشون میده حالا این اطلاعاتی که توی دیتابیس من هست دایم درحال تغییره من میخوام بدونه اینکه احتیاج باشه کاربر صفحه رو رفرش کنه اطلاعات چاپ شده براش بروزرسانی بشه میشه کدشو کامل بهم بدی یعنی خودت مجدد کد های اتصال به دیتابیس و چاپ اون متغیر و استفاده از آجاکس و بهم بدی؟
سلام. اصلا مشخص نیست که سایتتون چطوریه کدنویسیش به چه صورته برای همین باید با هزینه واگذاری کنید تا کدش براتون نوشته بشه