טרייטים לעומת ירושה
חלק מהיחידה תכנות מונחה עצמים במסלול ה-PHP של Coddy. שיעור 55 מתוך 91.
עכשיו, כשאתה מבין איך traits פועלות, בוא נבהיר מתי להשתמש ב-traits ומתי בירושה. שתי האפשרויות מאפשרות שימוש חוזר בקוד, אבל הן משרתות מטרות שונות ויש להן מאפיינים נבדלים.
ירושה יוצרת קשר של "הוא סוג של". מחלקת Dog שמרחיבה את Animal פירושה שכלב הוא בעל חיים. מחלקת הבת יורשת את הזהות של מחלקת האב, וניתן להשתמש בה בכל מקום שבו מצופה טיפוס האב.
Traits מספקים יכולת מסוג "יש לו". כשמחלקה משתמשת ב־trait בשם Loggable, יש לה פונקציונליות של רישום ביומן — אבל היא לא הופכת לרשם יומן. Traits מוסיפים התנהגות מבלי לשנות את מהות המחלקה.
<?php
// ירושה: Dog הוא Animal
class Animal {
public function breathe(): void {
echo "Breathing";
}
}
class Dog extends Animal {
public function bark(): void {
echo "Woof!";
}
}
// תכונה: ל-Dog יש יכולת רישום ביומן
trait Loggable {
public function log(string $msg): void {
echo "Log: $msg";
}
}
class Cat extends Animal {
use Loggable;
}
הבדלים עיקריים שכדאי לזכור:
| היבט | ירושה | Traits |
|---|---|---|
| קשר | הוא־סוג־של | יש לו יכולת |
| מגבלה | הורה יחיד בלבד | אפשר להשתמש בכמה Traits |
| בדיקת טיפוסים | עובדת עם instanceof | אין זהות טיפוס |
| מתאים ביותר ל־ | קשרים היררכיים | התנהגויות משותפות בין מחלקות שאינן קשורות |
השתמשו בירושה כאשר למחלקות יש זהות משותפת. השתמשו ב-traits כאשר מחלקות שאינן קשורות זקוקות לאותה פונקציונליות, מבלי להיות חלק מאותו עץ משפחה.
אתגר
קלבואו נבנה מערכת כלי רכב שמדגימה מתי להשתמש בירושה לעומת traits. תיצרו היררכיה של כלי רכב שמשתפים זהות משותפת באמצעות ירושה, ובמקביל יוסיפו יכולות רוחביות באמצעות traits.
תארגנו את הקוד שלכם בארבעה קבצים:
Trackable.php: צרו trait בשםTrackableשמספק יכולת מעקב GPS. ל-trait צריכים להיות:- מאפיין פרטי
$location(מחרוזת) - מתודה
setLocation(string $location)ששומרת את המיקום הנוכחי - מתודה
getLocation()שמחזירה"Location: [location]"
- מאפיין פרטי
Vehicle.php: צרו מחלקת בסיסVehicleשמבססת את היחס מסוג "הוא". כללו את קובץ ה-trait. השתמשו בקידום מאפיינים בבנאי כדי להגדיר מאפיין$brandמוגן. הוסיפו מתודהdescribe()שמחזירה"Vehicle: [brand]". המחלקה הזאת צריכה להשתמש ב-traitTrackable, מכיוון שלכל כלי הרכב בצי שלנו יהיה GPS.Car.php: צרו מחלקתCarשמרחיבה אתVehicle. כללו את קובץ Vehicle. השתמשו בקידום מאפיינים בבנאי כדי לקבל את המותג ואת המאפיין הפרטי$doors(מספר שלם). קראו לבנאי של מחלקת האב עם המותג. דרסו את המתודהdescribe()כדי שתחזיר"Car: [brand] with [doors] doors".main.php: כללו את קובץ Car. תקבלו שלושה קלטים: שם מותג, מספר דלתות ומחרוזת של מיקום. צרו מופע שלCar, הגדירו את המיקום שלו, ואז הדפיסו שתי שורות:- התוצאה של קריאה ל-
describe() - התוצאה של קריאה ל-
getLocation()
- התוצאה של קריאה ל-
שימו לב כיצד ירושה ו-traits פועלים יחד כאן: Car הוא Vehicle (הירושה מבססת זהות), ואילו ל-Vehicle יש יכולת מעקב (ה-trait מוסיף התנהגות). תוכלו להשתמש ב-instanceof Vehicle כדי לבדוק אם משהו הוא כלי רכב, אבל אין טיפוס "Trackable" שאפשר לבדוק מולו: זה ההבדל המרכזי בין שתי הגישות האלה.
נסו בעצמכם
<?php
// קובץ ראשי - יצירה ובדיקה של מופע Car
// TODO: לכלול את הקובץ Car.php
// קריאת הקלטים
$brand = trim(fgets(STDIN));
$doors = intval(trim(fgets(STDIN)));
$location = trim(fgets(STDIN));
// TODO: ליצור מופע Car עם brand ו-doors
// TODO: להגדיר את מיקום המכונית
// TODO: להדפיס את התוצאה של describe()
// TODO: להדפיס את התוצאה של getLocation()
?>השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות התכנות מונחה העצמים (OOP)
קבצים חיצונייםמבוא ל-OOPמחלקות לעומת אובייקטיםמילת המפתח $thisמתודותמאפייניםבנאי (__construct)הורס (__destruct)חזרה: מחשבון פשוט4ירושה
ירושה בסיסיתמילת המפתח parent::דריסת מתודותמילת המפתח finalמחלקות מופשטותסיכום – היררכיית עובדים7כימוס
ציבורי, מוגן, פרטימפרטי גישה לעומקמתודות גישה ועדכוןהסתרת מידעקידום פרמטרים בבנאי (8.0)סיכום – מערכת רישומי תלמידים2מרחבי שמות וטעינה אוטומטית
מבוא למרחבי שמותמילת המפתח useתקן הטעינה האוטומטית PSR-4הטוען האוטומטי של Composerסיכום – פרויקט מאורגן5ממשקים וחוזים
מבוא לממשקיםמימוש ממשקיםמימוש של כמה ממשקיםממשק לעומת מחלקה מופשטתרמזי טיפוסים עם ממשקיםסיכום - מחשבון צורות8מתודות קסם
מבוא למתודות קסם__toString ו־__debugInfo__get, __set, __isset, __unset__call ו־__callStatic__clone ושיבוט אובייקטים__serialize ו־__unserializeסיכום – אוסף מותאם אישית3מאפייני מחלקה
מאפייני מופע לעומת מאפיינים סטטייםקבועים במחלקותמתודות ומאפיינים סטטייםמאפיינים פרטיים ומוגניםמאפיינים לקריאה בלבד (PHP 8.1)סיכום – מנהל חשבון בנק6פולימורפיזם
בחינה מחדש של דריסת מתודותפולימורפיזם באמצעות ממשקיםרמזי טיפוסים וטיפוסי איחודקישור סטטי מאוחרסיכום — מעבד תשלומים9טרייטים
מבוא לטרייטיםשימוש במספר טרייטיםפתרון התנגשויות בין טרייטיםמתודות מופשטות בטרייטיםטרייטים לעומת ירושהתרגלו בעצמכם: קומפיילר PHP אונליין