תחי ישראל - אין לנו ארץ אחרת

תחי ישראל -אין לנו ארץ אחרת

מדריך להורשה ב-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

 

 

אהבתם? לא אהבתם? דרגו!

0 הצבעות, ממוצע 0 מתוך 5 כוכבים

 

 

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

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

שימו לב! הסקריפטים במדריכים מיועדים למטרות לימוד בלבד. כשאתם עובדים על הפרויקטים שלכם אתם צריכים להשתמש בספריות וסביבות פיתוח מוכחות, מהירות ובטוחות.

המשתמש באתר צריך להיות מודע לכך שאם וכאשר הוא מפתח קוד בשביל פרויקט הוא חייב לשים לב ולהשתמש בסביבת הפיתוח המתאימה ביותר, הבטוחה ביותר, היעילה ביותר וכמובן שהוא צריך לבדוק את הקוד בהיבטים של יעילות ואבטחה. מי אמר שלהיות מפתח זו עבודה קלה ?

השימוש שלך באתר מהווה ראייה להסכמתך עם הכללים והתקנות שנוסחו בהסכם תנאי השימוש.

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

 

 

ענה על השאלה הפשוטה הבאה כתנאי להוספת תגובה:

איך קוראים בעברית לצ`ופצ`יק של הקומקום?