פתרון התנגשויות בין טרייטים
חלק מהיחידה תכנות מונחה עצמים במסלול ה-PHP של Coddy. שיעור 53 מתוך 91.
כאשר שתי תכונות מגדירות מתודות בעלות אותו שם, PHP גורמת לשגיאה קטלנית. עליך לומר במפורש ל-PHP כיצד לטפל בהתנגשות הזאת באמצעות האופרטורים insteadof ו-as.
<?php
trait FileLogger {
public function log(string $message): void {
echo "File: $message";
}
}
trait DatabaseLogger {
public function log(string $message): void {
echo "DB: $message";
}
}
class Application {
use FileLogger, DatabaseLogger {
FileLogger::log insteadof DatabaseLogger;
DatabaseLogger::log as logToDatabase;
}
}
$app = new Application();
$app->log("Error occurred");
$app->logToDatabase("Error occurred");
פלט:
File: Error occurred
DB: Error occurredהאופרטור insteadof בוחר באיזו מתודה של trait להשתמש כשיש התנגשות. בדוגמה הזו, FileLogger::log מנצחת והופכת למתודת ברירת המחדל log(). האופרטור as יוצר כינוי, שמאפשר לך לגשת למתודה של ה-trait האחר תחת שם אחר.
אפשר גם להשתמש ב־as כדי לשנות את רמת הנראות של מתודה:
<?php
trait Greeting {
public function sayHello(): void {
echo "Hello!";
}
}
class Person {
use Greeting {
sayHello as private;
}
}
כך sayHello() הופכת לפרטית בתוך המחלקה Person, אף שהיא ציבורית ב־trait. פתרון התנגשויות מעניק לך שליטה מדויקת באופן שבו מתודות של trait משתלבות במחלקות שלך.
אתגר
קלבואו נבנה מערכת התראות שבה ערוצים שונים יכולים לשלוח הודעות, אך עלינו לפתור התנגשויות כשכמה traits מספקים שיטה בעלת אותו שם.
תארגן את הקוד שלך בארבעה קבצים:
EmailNotifier.php: צור trait בשםEmailNotifierעם שיטהnotify(string $message)שמחזירה"Email: [message]".SmsNotifier.php: צור trait בשםSmsNotifierעם שיטהnotify(string $message)שמחזירה"SMS: [message]".AlertService.php: צור מחלקה בשםAlertServiceשמשתמשת בשני ה-traits. מכיוון שלשני ה-traits יש שיטה בשםnotify(), יהיה עליך לפתור את ההתנגשות:- השתמש ב-
EmailNotifier::notifyכשיטת ברירת המחדלnotify() - צור כינוי
notifyBySmsלשיטהSmsNotifier::notify
notifyAll(string $message)שקוראת לשתי שיטות ההתראה ומחזירה אותן משורשרות בשורות נפרדות.- השתמש ב-
main.php: כלול את כל הקבצים הדרושים וצור מופע שלAlertService. תתקבל קלט אחד: מחרוזת הודעה. הדפס שלוש שורות:- התוצאה של קריאה ל-
notify()עם ההודעה - התוצאה של קריאה ל-
notifyBySms()עם ההודעה - התוצאה של קריאה ל-
notifyAll()עם ההודעה
- התוצאה של קריאה ל-
הדוגמה הזאת מראה איך insteadof קובע איזו שיטה של trait גוברת כשיש התנגשות בין שמות, בעוד as מאפשר לך להמשיך לגשת לשיטה של ה-trait האחר בשם שונה.
נסו בעצמכם
<?php
require_once 'AlertService.php';
// קרא את הקלט
$message = trim(fgets(STDIN));
// TODO: צור מופע של AlertService
// TODO: הדפס את התוצאה של הקריאה ל-notify() עם ההודעה
// TODO: הדפס את התוצאה של הקריאה ל-notifyBySms() עם ההודעה
// TODO: הדפס את התוצאה של הקריאה ל-notifyAll() עם ההודעה
?>השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
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 אונליין