Menu
Coddy logo textTech

הרכבה לעומת הורשה

חלק מהיחידה תכנות מונחה עצמים במסלול ה-Dart של Coddy. שיעור 82 מתוך 110.

למדת שירושה יוצרת קשר של "הוא-סוג-של" — Dog הוא Animal. אבל יש גישה חזקה נוספת: הרכבה, שיוצרת קשר של "יש-לו". במקום לרשת התנהגות, מחלקה מכילה מופעים של מחלקות אחרות ומאצילה להן את העבודה.

נבחן מחלקה בשם Car. באמצעות ירושה, אולי תנסו להרחיב מחלקה בשם Engine — אבל מכונית אינה מנוע, יש לה מנוע:

class Engine {
  void start() => print('Engine started');
}

class Car {
  final Engine _engine = Engine();  // קומפוזיציה: ל-Car יש Engine
  
  void start() {
    _engine.start();  // האצל את הפעולה ל-_engine
    print('Car is ready to drive');
  }
}

void main() {
  var car = Car();
  car.start();
}

היתרון המרכזי של הרכבה הוא הגמישות. עם ירושה, את/ה מוגבל/ת למחלקת אב אחת. עם הרכבה, אפשר לשלב כמה רכיבים ואפילו להחליף ביניהם בזמן ריצה:

class ElectricEngine {
  void start() => print('Electric motor humming');
}

class HybridCar {
  Engine? _gasEngine;
  ElectricEngine? _electricEngine;
  
  HybridCar({bool useElectric = false}) {
    if (useElectric) {
      _electricEngine = ElectricEngine();
    } else {
      _gasEngine = Engine();
    }
  }
}

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

challenge icon

אתגר

קל

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

תארגן את הקוד שלך בשלושה קבצים:

  • components.dart: צור שתי מחלקות רכיבים שמייצגות חלקי מחשב:
    • מחלקת CPU עם String brand ו-double speedGHz. כלול מתודת process() שמחזירה מחרוזת: [brand] processing at [speedGHz]GHz
    • מחלקת Memory עם int sizeGB. כלול מתודת load() שמחזירה מחרוזת: Loading [sizeGB]GB of data
  • computer.dart: צור מחלקת Computer שמשתמשת בהרכבה כדי לשלב את הרכיבים. המחשב שלך צריך:
    • להכיל שדה String name
    • להכיל מופע של CPU ומופע של Memory (הרכבה — למחשב יש את החלקים האלה)
    • לקבל את כל הערכים הדרושים דרך הבנאי שלו כדי ליצור את שני הרכיבים בתוכו
    • להכיל מתודת boot() שמעבירה את העבודה לשני הרכיבים ומדפיסה שלוש שורות: שם המחשב ואחריו starting..., לאחר מכן התוצאה של מתודת ה-process של ה-CPU, ולבסוף התוצאה של מתודת ה-load של ה-Memory
    • להכיל מתודת specs() שמחזירה מחרוזת המתארת את המערכת: [name]: [brand] [speedGHz]GHz, [sizeGB]GB RAM
  • main.dart: ייבא את הקבצים שלך והדגם את ההרכבה בפעולה:
    • צור Computer בשם Workstation עם CPU של Intel שפועל במהירות 3.5 GHz ועם 16 GB של זיכרון
    • קרא למתודת boot()
    • הדפס את התוצאה של specs()

שים לב שמחלקת Computer לא מרחיבה את CPU או את Memory — היא מכילה אותם ומעבירה אליהם את העבודה. זהו קשר מסוג "יש-לו" שההרכבה יוצרת!

פלט צפוי:

Workstation starting...
Intel processing at 3.5GHz
Loading 16GB of data
Workstation: Intel 3.5GHz, 16GB RAM

נסו בעצמכם

import 'computer.dart';

void main() {
  // TODO: צרו אובייקט Computer בשם "Workstation" עם:
  // - מעבד Intel הפועל בתדר 3.5 GHz
  // - זיכרון בנפח 16 GB

  // TODO: קראו למתודה boot()

  // TODO: הדפיסו את התוצאה של specs()
}
quiz iconבחנו את עצמכם

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

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

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