מחלקות מופשטות
חלק מהיחידה תכנות מונחה עצמים במסלול ה-PHP של Coddy. שיעור 25 מתוך 91.
מחלקה מופשטת היא מחלקה שלא ניתן ליצור ממנה מופע ישירות. היא משמשת כתבנית למחלקות אחרות, ומגדירה מתודות שמחלקות הבת חייבות לממש. יוצרים מחלקה מופשטת באמצעות מילת המפתח abstract.
<?php
abstract class Shape {
protected $color;
public function __construct($color) {
$this->color = $color;
}
abstract public function calculateArea();
public function getColor() {
return $this->color;
}
}
class Rectangle extends Shape {
private $width;
private $height;
public function __construct($color, $width, $height) {
parent::__construct($color);
$this->width = $width;
$this->height = $height;
}
public function calculateArea() {
return $this->width * $this->height;
}
}
$rect = new Rectangle("blue", 5, 3);
echo $rect->calculateArea();
פלט:
15המחלקה Shape מצהירה על מתודה מופשטת calculateArea() בלי לספק לה מימוש. כל מחלקה שיורשת את Shape חייבת לממש את המתודה הזאת. שימו לב שמחלקות מופשטות יכולות להכיל גם מתודות רגילות כמו getColor(), שמחלקות יורשות מקבלות ישירות ממחלקת האב.
מתודות מופשטות מגדירות מה מחלקת צאצא חייבת לעשות, אך לא איך. כך מובטח שלכל הצורות תהיה מתודת calculateArea(), ובו בזמן כל צורה תוכל לחשב את השטח שלה באופן שונה.
נקודה מרכזית: מחלקות מופשטות משלבות את המבנה של ירושה עם דרישות מחייבות. השתמשו בהן כשרוצים לשתף קוד בין מחלקות קשורות, תוך הבטחה שכל מחלקת צאצא תממש מתודות מסוימות.
אתגר
קלבואו נבנה מערכת נגן מדיה שמדגימה כיצד מחלקות מופשטות אוכפות חוזה, ובו בזמן מאפשרות לסוגי מדיה שונים לממש את אופן ההפעלה שלהם.
תארגנו את הקוד שלכם בשלושה קבצים:
Media.php: הגדירו מחלקה מופשטת בשםMediaשמשמשת תבנית לכל סוגי המדיה. צריכה להיות לה תכונה מוגנת בשם$titleובנאי שמקבל את הכותרת ומגדיר אותה. כללו מתודה מופשטת בשםplay()שמחלקות יורשות חייבות לממש. הוסיפו גם מתודה רגילה בשםgetTitle()שמחזירה את הכותרת. המתודה הממומשת הזאת תעבור בירושה לכל המחלקות היורשות.Song.php: הגדירו מחלקה בשםSongשיורשת אתMedia. כללו את קובץ Media בתחילת הקובץ. למחלקה הזאת יש תכונה נוספת בשם$artist. הבנאי צריך לקבל כותרת ושם אמן: השתמשו ב-parent::__construct()עבור הכותרת, ואז הגדירו בעצמכם את האמן. ממשו את המתודה הנדרשתplay()כך שתחזיר את"Playing song: [title] by [artist]".Podcast.php: הגדירו מחלקה בשםPodcastשיורשת אתMedia. כללו את קובץ Media בתחילת הקובץ. למחלקה הזאת יש תכונה נוספת בשם$episode(מספר שלם). הבנאי צריך לקבל כותרת ומספר פרק: השתמשו ב-parent::__construct()עבור הכותרת, ואז הגדירו את מספר הפרק. ממשו את המתודה הנדרשתplay()כך שתחזיר את"Playing podcast: [title] - Episode [episode]".
בקובץ main.php, כללו גם את קובץ Song וגם את קובץ Podcast. תקבלו ארבעה ערכי קלט: כותרת השיר, שם האמן, כותרת הפודקאסט ומספר הפרק (בתור מחרוזת שיש להמיר למספר שלם). צרו אובייקט Song ואובייקט Podcast עם הערכים האלה. הדפיסו את התוצאה של קריאה ל-play() של השיר תחילה, ולאחר מכן של הפודקאסט, כל אחד בשורה משלו.
האתגר הזה מדגים כיצד מחלקות מופשטות מגדירות חוזה: לכל סוג מדיה חייבת להיות מתודה play(), אך כל סוג מממש אותה באופן שונה. אי אפשר ליצור מופע ישירות של המחלקה המופשטת Media; היא קיימת רק כדי לספק מבנה ופונקציונליות משותפת למחלקות היורשות שלה.
נסו בעצמכם
<?php
require_once 'Song.php';
require_once 'Podcast.php';
// קרא את הקלטים
$songTitle = trim(fgets(STDIN));
$artistName = trim(fgets(STDIN));
$podcastTitle = trim(fgets(STDIN));
$episodeNumber = intval(trim(fgets(STDIN)));
// TODO: צור אובייקט Song עם songTitle ו-artistName
// TODO: צור אובייקט Podcast עם podcastTitle ו-episodeNumber
// TODO: הדפס את התוצאה של קריאה ל-play() על השיר
// TODO: הדפס את התוצאה של קריאה ל-play() על הפודקאסט
?>השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
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פולימורפיזם
בחינה מחדש של דריסת מתודותפולימורפיזם באמצעות ממשקיםרמזי טיפוסים וטיפוסי איחודקישור סטטי מאוחרסיכום — מעבד תשלומיםתרגלו בעצמכם: קומפיילר PHP אונליין