מערך שיעור: Inheritance ו-Polymorphism
משך: יום לימוד מלא — 6 שעות אקדמיות (270 דקות).
מטרת השיעור: הסטודנטים יבינו ירושה ככלי למניעת כפילות ולשיקוף יחס “הוא סוג של”, ו-Polymorphism ככלי לקוד אחד שעובד על הרבה סוגים, במקום שרשראות של if.
בסוף השיעור הסטודנטים צריכים:
- לבנות היררכיה עם
super().__init__, Override והרחבה עםsuper().method(), ולהחליט עם מבחן is-a אם ירושה מתאימה. - להחליף שרשרת
if type == ...בהיררכיה עם מתודה פולימורפית, ולהסביר את היתרון בהוספת סוג חדש. - להשתמש נכון ב-
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. כמה מקומות בקוד צריך לשנות?”
מהלך:
- לכתוב על הלוח את גרסת ה-if: 6 פונקציות × שרשרת if. התשובה: 6 מקומות, ואם שוכחים אחד, יש באג.
- לשאול: “איך הייתם רוצים שזה יעבוד?” ולכוון ל"שהתשלום עצמו יידע לחייב, להחזיר ולחשב עמלה".
- לבנות את ההיררכיה עם הכיתה.
- להוסיף ApplePay מול הכיתה: Class אחת, ולהריץ את
checkoutהקיים.
מה המרצה מראה בסוף: שני הקודים זה לצד זה. בגרסת ה-if מסמנים בצבע את כל השורות שצריך לגעת בהן כדי להוסיף סוג (פזורות על כל הקובץ). בגרסה הפולימורפית מסמנים רק את ה-Class החדשה (בלוק אחד). משפט סיום: “קוד טוב הוא קוד שמוסיפים לו, ולא קוד שמשנים. Polymorphism הופך ‘להוסיף סוג חדש’ מניתוח לב פתוח להדבקת חלק חדש.”