Menu
Coddy logo textTech

מתודות מופשטות בטרייטים

חלק מהיחידה תכנות מונחה עצמים במסלול ה-PHP של Coddy. שיעור 54 מתוך 91.

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

כאשר trait מגדיר מתודה מופשטת, כל מחלקה שמשתמשת ב-trait הזה חייבת לממש אותה:

<?php
trait Notifiable {
    abstract public function getEmail(): string;
    
    public function sendNotification(string $message): void {
        echo "Sending to " . $this->getEmail() . ": $message";
    }
}

class User {
    use Notifiable;
    
    public function __construct(private string $email) {}
    
    public function getEmail(): string {
        return $this->email;
    }
}

$user = new User("john@example.com");
$user->sendNotification("Welcome!");

פלט:

Sending to john@example.com: Welcome!

ה-trait מספק את המתודה sendNotification(), אך מסתמך על כך שהמחלקה תממש את getEmail(). כך נוצר דפוס רב־עוצמה שבו ה-trait מטפל בלוגיקה המשותפת, ובמקביל מעביר את הפרטים הייחודיים למחלקה למחלקה שמממשת אותו.

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

challenge icon

אתגר

קל

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

תארגנו את הקוד שלכם בשלושה קבצים:

  • Discountable.php: צרו trait בשם Discountable שמספק פונקציונליות להנחות. ה-trait צריך לכלול:
    • מתודה מופשטת getBasePrice(): float שהמחלקות המשתמשות ב-trait הזה חייבות לממש
    • מתודה applyDiscount(int $percent) שמחשבת ומחזירה את המחיר לאחר החלת אחוז ההנחה על מחיר הבסיס
    • מתודה getFinalPrice(int $percent) שמחזירה מחרוזת בפורמט: "Final price: $[discounted_price]" עם 2 ספרות אחרי הנקודה העשרונית
    ה-trait מטפל בכל חישובי ההנחה, אך מסתמך על כל מחלקה כדי שתספק לו את מחיר הבסיס.
  • Product.php: צרו מחלקה Product שמשתמשת ב-trait Discountable. כללו את קובץ ה-trait. השתמשו בקידום מאפיינים בבנאי כדי להגדיר $name פרטי (מחרוזת) ו-$price פרטי (מספר עשרוני). ממשו את המתודה הנדרשת getBasePrice() כדי להחזיר את מחיר המוצר.
  • main.php: כללו את קובץ Product. תקבלו שלוש קלטים: שם מוצר, מחיר ואחוז הנחה. צרו מופע של Product והדפיסו שתי שורות:
    • מחיר הבסיס בפורמט "Base: $[price]" עם 2 ספרות אחרי הנקודה העשרונית
    • התוצאה של קריאה ל-getFinalPrice() עם אחוז ההנחה

התבנית הזו עוצמתית מכיוון שניתן להשתמש ב-trait Discountable בכל מחלקה, למשל מוצרים, שירותים ומינויים, כל עוד הן מממשות את getBasePrice(). ה-trait מספק את לוגיקת ההנחה המשותפת, בעוד שכל מחלקה מגדירה מאין מגיע מחיר הבסיס שלה.

נסו בעצמכם

<?php

require_once 'Product.php';

// קרא את הקלטים
$name = trim(fgets(STDIN));
$price = floatval(trim(fgets(STDIN)));
$discountPercent = intval(trim(fgets(STDIN)));

// TODO: צור מופע של Product עם השם והמחיר

// TODO: הדפס את מחיר הבסיס בפורמט "Base: $[price]" עם 2 ספרות אחרי הנקודה העשרונית

// TODO: הדפס את התוצאה של קריאה ל־getFinalPrice() עם אחוז ההנחה

?>
quiz iconבחנו את עצמכם

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

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

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