Menu
Coddy logo textTech

פתרון התנגשויות בין טרייטים

חלק מהיחידה תכנות מונחה עצמים במסלול ה-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 משתלבות במחלקות שלך.

challenge icon

אתגר

קל

בואו נבנה מערכת התראות שבה ערוצים שונים יכולים לשלוח הודעות, אך עלינו לפתור התנגשויות כשכמה 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() עם ההודעה
?>
quiz iconבחנו את עצמכם

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

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר PHP אונליין