# מערך שיעור: Inheritance ו-Polymorphism<no value>

**משך:** יום לימוד מלא — 6 שעות אקדמיות (270 דקות).

**מטרת השיעור:** הסטודנטים יבינו ירושה ככלי ל**מניעת כפילות** ולשיקוף יחס "הוא סוג של", ו-Polymorphism ככלי ל**קוד אחד שעובד על הרבה סוגים**, במקום שרשראות של `if`.

**בסוף השיעור הסטודנטים צריכים:**

1. לבנות היררכיה עם `super().__init__`, Override והרחבה עם `super().method()`, ולהחליט עם מבחן is-a אם ירושה מתאימה.
2. להחליף שרשרת `if type == ...` בהיררכיה עם מתודה פולימורפית, ולהסביר את היתרון בהוספת סוג חדש.
3. להשתמש נכון ב-`isinstance` מול `type`, וליצור היררכיית Exceptions משלהם.

**דגש קריטי:** **Polymorphism הוא המטרה, ירושה היא הכלי.** הרגע החשוב ביום הוא כשמוסיפים `ApplePay` ו-`checkout` לא משתנה. אם הסטודנטים יוצאים עם "ירושה = העתקת קוד חכמה" בלבד, פספסנו.

---

## מהלך השיעור

| חלק בשיעור | משך | הערות ודגשים |
|---|---|---|
| פתיחה: חשבון החיסכון מנושא OOP – Classes ואובייקטים | 10 דק' | לחזור לשאלה הפתוחה מנושא OOP – Classes ואובייקטים. |
| למה ירושה, Parent/Child, תחביר | 40 דק' | Employee/Manager הכפולים, ואז הירושה. Animal/Dog/Cat. מבחן is-a על הלוח. |
| super() ו-Override | 50 דק' | הבעיה של Truck. הדגמה חיה של 3 הטעויות (בלי super, self מיותר, רקורסיה). Employee/Manager/Intern. |
| הפסקה | 15 דק' | |
| Polymorphism | 45 דק' | התשלומים עם if → עם Classes. **הוספת ApplePay בלייב**. Duck Typing עם GiftCard. |
| type / isinstance / issubclass + Exceptions | 35 דק' | היררכיית ה-Exceptions על הלוח. BankError עם סדר except. ההפתעה של bool/int. |
| הפסקה | 15 דק' | |
| תרגול + Mini Project | 50 דק' | מערכת שכר. לבדוק שאין `if isinstance` ב-`run_payroll`. |
| בדוק את עצמך | 10 דק' | |

---

## דגשים להעברת השיעור

- **לחזור לדוגמת הבנק מנושא OOP – Classes ואובייקטים.** ההמשכיות מחזקת את ההבנה: אותה בעיה, פתרון שנבנה בהדרגה.
- **ציור היררכיה** על הלוח לכל דוגמה (עץ עם חצים למעלה), ולסמן ליד כל Class אילו מתודות היא מגדירה. כשקוראים מתודה, "לטפס" עם האצבע עד שמוצאים.
- **`self` בתוך מתודה של Parent** הוא תמיד האובייקט האמיתי, וזה המפתח להבנת Template Method ו-Polymorphism. להדגים עם `describe` של Employee שקורא `self.monthly_cost()`.
- **Composition רק כרמז.** ב"מכונית יורשת ממנוע" לעצור ולומר "יש לו ≠ הוא סוג של. מחר נלמד מה עושים". לא להיכנס לזה היום.
- **Multiple Inheritance** — להציג **רק** בהקשר של Exceptions (`InvalidAmountError(BankError, ValueError)`). לא ללמד MRO ולא ירושה מרובה כללית.
- **`bool` יורש מ-`int`** — פרט קטן שמבהיר הרבה על isinstance, ומונע באג אמיתי בולידציה.
- **Exceptions משלנו** סוגרים מעגל שנפתח בנושא Python (`raise`). להזכיר במפורש.

---

## מושגים

| מושג | הסבר קצר |
|---|---|
| Inheritance | Child מקבלת את כל מה שיש ל-Parent. |
| Parent / Base / Superclass | ה-Class הכללית. |
| Child / Derived / Subclass | ה-Class שיורשת. |
| is-a | מבחן להתאמת ירושה: "X הוא סוג של Y". |
| has-a | "ל-X יש Y". מתאים ל-Composition, לא לירושה. |
| `super()` | גישה לגרסה של ה-Parent על אותו self. |
| Method Overriding | Child מגדירה מתודה באותו שם, והגרסה שלה מנצחת. |
| Extend | Override שמשתמש ב-`super().method()` ומוסיף. |
| Polymorphism | אותה קריאה, התנהגות שונה לפי סוג. |
| Common Interface | המתודות שכל הסוגים חולקים. |
| `NotImplementedError` | סימון מתודה שכל Child חייבת לממש. |
| Template Method | מתודה ב-Parent שקוראת למתודות שה-Child מממשת. |
| Duck Typing | "מה שיודע לעשות X, אפשר להשתמש בו כ-X". |
| `type` / `isinstance` / `issubclass` | סוג מדויק / סוג של (כולל ירושה) / יחס בין Classes. |
| Custom Exception | Class שיורשת מ-Exception. |

---

## תרגיל חשיבה

**שאלת פתיחה (לפני Polymorphism):** "יש לכם חנות אונליין עם 3 אמצעי תשלום. יש 6 פונקציות במערכת שמטפלות בתשלומים: חיוב, החזר, עמלה, קבלה, דוח, ובדיקת הונאה. המנכ"ל מודיע: מחר מוסיפים Apple Pay. כמה מקומות בקוד צריך לשנות?"

**מהלך:**

1. לכתוב על הלוח את גרסת ה-if: 6 פונקציות × שרשרת if. התשובה: 6 מקומות, ואם שוכחים אחד, יש באג.
2. לשאול: "איך הייתם רוצים שזה יעבוד?" ולכוון ל"שהתשלום עצמו יידע לחייב, להחזיר ולחשב עמלה".
3. לבנות את ההיררכיה עם הכיתה.
4. **להוסיף ApplePay מול הכיתה:** Class אחת, ולהריץ את `checkout` הקיים.

**מה המרצה מראה בסוף:** שני הקודים זה לצד זה. בגרסת ה-if מסמנים בצבע את כל השורות שצריך לגעת בהן כדי להוסיף סוג (פזורות על כל הקובץ). בגרסה הפולימורפית מסמנים רק את ה-Class החדשה (בלוק אחד). משפט סיום: "**קוד טוב הוא קוד שמוסיפים לו, ולא קוד שמשנים.** Polymorphism הופך 'להוסיף סוג חדש' מניתוח לב פתוח להדבקת חלק חדש."
