נגישות       נגישות
שינוי גודל טקסט:
א א א
שינוי צבעי האתר:
? מקשי קיצור:

לחיצה חוזרת ונשנית על המקש Tab תעביר אתכם בין הקישורים והאזורים השונים בעמוד.

הפעלת מקשי הקיצור תלויה בדפדפן שבו אתם משתמשים.

Internet Explorer, Chrome ובגרסאות ישנות של Firefox: לחצו על מקש Alt ועל מקש המספר או האות על-פי הרשימה. ב Firefox 3 ומעלה: לחצו על המקשים Alt + Shift + המספר או האות.

S - עבור לתוכן הדף
L - חיפוש
1- עמוד הבית
2 - פרוייקטים
3 - מדריכים
4 - אודות
5 - צרו קשר
6 - הצהרת נגישות
 

מדריך להורשה ב-PHP מונחה עצמים

מחבר:
בתאריך:

אחד היתרונות העיקריים של תכנות מונחה עצמים היא היכולת להפחית בכמות הקוד הודות לשימוש חוזר בקוד באמצעות הורשה. בהורשה יש לנו מחלקה הורה (super class) שמכילה מתודות ותכונות, ומחלקה או מחלקות יורשות (sub class) שיכולות להשתמש במתודות ובתכונות של המחלקה ההורה. מזה נובעת יעילות הקוד, מפני שבמקום לכתוב את אותו הקוד במספר מקומות שונים, אנו יכולים לכתוב את הקוד רק במקום אחד, שהוא הקלאס ההורה, ולחזור ולהשתמש בו כמה שנרצה בקלאסים היורשים.

כדי לציין שמחלקה אחת יורשת ממחלקה אחרת אנו משתמשים במילת המפתח extends. כך נראה המקרה הכללי:

class Parent{
  //קוד ההורה
}
 
class Child extends Parent{
  //קוד הילד
}

בדוגמת הקוד הבאה המחלקה SportsCar יורשת את המחלקה Car, ולפיכך מקבלת את התכונות והמתודות של המחלקה ההורה.

//המחלקה של ההורה
class Car {
  //התכונה
  private $model;
 
  //מתודות
  public function setModel($model){
    $this -> model = $model;
  }
 
  public function hello(){
    return "beep! I am a <i>" . $this -> model . "</i><br />";
  }
}
 
//המחלקה היורשת
class SportsCar extends Car{
  //לא הגדרנו לה תכונות ומתודות
}
 
 
//יצירת האינסטנס
$newSportsCar = new SportsCar();
 
//הזנת האינסטנס בנתונים
$newSportsCar -> setModel('Mercedes Benz');
 
//הפעלת אחת המתודות שהוא ירש
echo $newSportsCar -> hello();

והתוצאה:

beep! I am a Mercedes Benz

 

eBook cover The essentials of Object Oriented PHP

 

המחלקה היורשת יכולה להוסיף תכונות ומתודות משלה

כפי שהמחלקה היורשת יכולה לקבל תכונות ומתודות של המחלקה ממנה היא יורשת, היא יכולה להוסיף תכונות ומתודות משלה.

בדוגמת הקוד הבאה, נוסיף למחלקה היורשת מתודות ותכונות משלה.

//המחלקה של ההורה
class Car {
  //התכונה
  private $model;
 
  //מתודות
  public function setModel($model){
    $this -> model = $model;
  }
 
  public function hello(){
    return 'beep! I am a <i>' . $this -> model . '</i><br />';
  }
}
 
//המחלקה היורשת
class SportsCar extends Car{
  //נוסיף למחלקה היורשת תכונות ומתודות משל עצמה
  public $quality = 'very fast';
  public function __construct(){
    echo 'I am a '.__CLASS__.', so I am <i>'.$this->quality.'</i>.<br />';
  }
}
 
 
//יצירת האינסטנס
$newSportsCar = new SportsCar();
 
//הזנת האינסטנס בנתונים
$newSportsCar -> setModel('Mercedes Benz');
 
//הפעלת אחת המתודות שהוא ירש
echo $newSportsCar -> hello();

והתוצאה:

I am a SportsCar, so I am very fast.
beep! I am a Mercedes Benz

 

רמת גישה protected

במדריך קודם הראיתי את רמות הגישה:public, שמנגישה תכונות ומתודות לכל הרמות, ו-private שמאפשרת גישה רק בתוך המחלקה. רמת הגישה השלישית היא protected שמאפשרת גישה מתוך המחלקה או מתוך המחלקות שיורשות אותה בלבד.

בדוגמה הראשונה, נראה מה קורה כשאנו נותנים למשתנה $model, שנמצא בהורה, רמת גישה private, ואף על פי כן אנו מנסים לגשת אל המשתנה מהמחלקה היורשת.

class Car {
  //שים לב התכונה היא
  //private
  //ולכן ניתן לגשת אליה רק מתוך הקלאס
  private $model;
 
  //מתודות
  public function setModel($model){
    $this -> model = $model;
  }
}
 
//המחלקה היורשת
class SportsCar extends Car{
  //מנסה להשתמש בתכונה שהיא
  //private
  public function hello(){
    return "beep! I am a <i>" . $this -> model . "</i><br />";
  }
}
 
//יצירת האינסטנס
$newSportsCar = new SportsCar();
 
//הזנת האינסטנס בנתונים
$newSportsCar -> setModel('Mercedes Benz');
 
//הפעלת אחת המתודות שהוא ירש
echo $newSportsCar -> hello();

התוצאה היא שגיאה שהורגת את הסקריפט מפני ש-private נועל את המשתנה בתוך הקלאס ולא מאפשר גישה אליו מבחוץ. כך נראית השגיאה:

Notice: Undefined property: SportsCar::$model

 

נתקן את המצב על ידי כך שנגדיר את המשתנה $model ברמת גישה protected, ועל ידי כך נאפשר למתודה שנמצאת במחלקה היורשת גישה אל המשתנה.

class Car {
  //נפתור את הבעיה מפני שהתכונה יכולה לעבור למחלקה היורשת כשהיא
  //protected
  protected $model;
 
  //מתודות
  public function setModel($model){
    $this -> model = $model;
  }
}
 
//המחלקה היורשת
class SportsCar extends Car{
  //יכול להשתמש בתכונה מפני שהיא עכשיו
  //protected
  //ועל כן נגישה למחלקה היורשת
  public function hello(){
    return "beep! I am a <i>" . $this -> model . "</i><br />";
  }
}
 
//יצירת האינסטנס
$newSportsCar = new SportsCar();
 
//הזנת האינסטנס בנתונים
$newSportsCar -> setModel('Mercedes Benz');
 
//הפעלת אחת המתודות שהוא ירש
echo $newSportsCar -> hello();

עכשיו זה עובד, והתוצאה בהתאם:

beep! I am a Mercedes Benz

 

דריסה של תכונות ומתודות על ידי המחלקה היורשת

כפי שלמחלקה היורשת יכולות להיות תכונות ומתודות משלה, היא יכול להגדיר מחדש (לדרוס) את התכונות והמתודות של המחלקה ההורה. בדוגמה, התכונה והמתודה שמקורם בהורה נדרסים על ידי תכונה ומתודה באותו שם במחלקה היורשת.

class Car {
  //התכונה
  protected $model = 'Mercedes Benz';
 
  //המתודה
  public function hello(){
    return "beep! I am a <i>" . $this -> model . "</i><br />";
  }
}
 
//המחלקה היורשת
class SportsCar extends Car{
  //התכונה הדורסת
  protected $model = "BMW";
 
  //המתודה הדורסת
  public function hello(){
    return "Hallo! I am a <i>" . $this -> model . "</i><br />";
  }
}
 
 
//יצירת האינסטנס
$newSportsCar = new SportsCar();
 
//הפעלת המתודה שלו
echo $newSportsCar -> hello();

והתוצאה:

Hallo! I am a BMW

 

מניעת דריסה של מתודות על ידי המחלקה היורשת

כדי למנוע מצב שהמחלקה היורשת דורסת מתודה של המחלקה ההורה, נגדיר את המתודה בהורה באמצעות מילת המפתח final. לדוגמה:

class Car {
 
  protected $model = 'Mercedes Benz';
 
  //נכריז על המתודה כ
  //final
  //למניעת דריסה על ידי הקלאס היורש
  final public function hello(){
    return "beep! I am a <i>" . $this -> model . "</i><br />";
  }
}
 
//המחלקה היורשת
class SportsCar extends Car{
  //התכונה הדורסת
  protected $model = "BMW";
 
  //המתודה שמנסה לדרוס אבל
  //final
  //מונע זאת ממנה
  public function hello(){
    return "Hallo! I am a <i>" . $this -> model . "</i><br />";
  }
}
 
 
//יצירת האינסטנס
$newSportsCar = new SportsCar();
 
//הפעלת המתודה שלו
echo $newSportsCar -> hello();

וכתוצאה מכך לא נוכל לדרוס את המתודה במחלקה היורשת. כפי שניתן לראות מהודעת השגיאה הבאה שייצר הסקריפט:

Fatal error: Cannot override final method Car::hello()

 

המדריך מבוסס על "The essentials of Object Oriented PHP" שמלמד PHP מונחה עצמים באמצעות דוגמאות ותרגילים הקליקו על התמונה כדי לרכוש את ה-eBook:

eBook cover The essentials of Object Oriented PHP

 

לכל מדריכי ה-PHP

 

הוסף תגובה חדשה

 

= 8 + 5