דריסת מתודות (@Override)
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Java של Coddy. שיעור 22 מתוך 87.
דריסת מתודות מאפשרת לתת־מחלקה לספק מימוש משלה למתודה שכבר הוגדרה במחלקת האב שלה. כך מחלקות צאצא מתאימות אישית התנהגות שירשו כדי שתענה על הצרכים הספציפיים שלהן.
כשאת דורס/ת מתודה, הגרסה של תת־המחלקה מחליפה לחלוטין את הגרסה של מחלקת האב עבור אובייקטים מאותה תת־מחלקה. שם המתודה והפרמטרים שלה חייבים להיות זהים לאלה של מתודת האב, וסוג ההחזרה חייב להיות זהה לסוג של מתודת האב (או תת־סוג שלו):
public class Animal {
public void makeSound() {
System.out.println("Some generic sound");
}
}
public class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Woof!");
}
}
public class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("Meow!");
}
}ההערה @Override מציינת למהדר שבכוונתך לדרוס מתודת אב. אף שהיא אופציונלית, מומלץ מאוד להשתמש בה, כי המהדר יזהה שגיאות אם תקליד בטעות את שם המתודה באופן שגוי או תשתמש בפרמטרים שגויים:
@Override
public void makeSound() { } // נכון - המהדר מאמת זאת
public void makesound() { } // שגיאת הקלדה! יוצרת מתודה חדשה במקום לדרוס את הקיימתכשקוראים למתודה שנדרסה, Java מריצה את הגרסה ששייכת לסוג האובייקט בפועל:
Dog dog = new Dog();
dog.makeSound(); // פלט: Woof!
Cat cat = new Cat();
cat.makeSound(); // פלט: Meow!זכור מהשיעור הקודם שאפשר להשתמש ב־super.methodName() בתוך מתודה שנדרסה אם עדיין רוצים לכלול את ההתנהגות של מחלקת האב לצד הקוד החדש שלך.
אתגר
קלבואו נבנה מערכת התראות שמדגימה כיצד מחלקות יורשות יכולות לדרוס מתודות של מחלקת האב כדי לספק התנהגות ייחודית משלהן. תוכלו לראות כיצד ההערה @Override עוזרת לאתר טעויות, וכיצד כל מחלקה יורשת יכולה להתאים אישית מתודות שעברו בירושה.
תיצרו שלושה קבצים כדי לארגן את הקוד שלכם:
Notification.java: צרו את מחלקת האב שמייצגת התראה כללית. היא צריכה לכלול:- שדה פרטי עבור
message(String) - בנאי שמקבל את ההודעה
- מתודה
getMessage()שמחזירה את ההודעה - מתודה
send()שמדפיסה:Sending notification: [message]
- שדה פרטי עבור
EmailNotification.java: צרו מחלקה יורשת שמרחיבה את Notification ומתאימה אישית את אופן שליחת ההתראות בדוא״ל:- שדה פרטי עבור כתובת הדוא״ל של
recipient(String) - בנאי שמקבל גם את ההודעה וגם את הנמען, ומשתמש ב-
super(message)עבור החלק של מחלקת האב - דרסו את המתודה
send()באמצעות ההערה@Overrideכדי להדפיס:Emailing [recipient]: [message]
- שדה פרטי עבור כתובת הדוא״ל של
Main.java: הדגימו כיצד אותו שם מתודה יוצר התנהגות שונה בהתאם לסוג האובייקט. תקבלו שתי קלטים: הודעה וכתובת דוא״ל. צרו גם Notification רגילה וגם EmailNotification עם אותה הודעה, ואז קראו ל-send()עבור כל אחת מהן כדי לראות את הפלטים השונים.
תקבלו שתי קלטים: ההודעה (String) וכתובת הדוא״ל של הנמען (String).
הפלט שלכם צריך להציג שתי שורות - תחילה מהמתודה send() של מחלקת האב, ולאחר מכן מהגרסה שנדרסה ב-EmailNotification. כך מודגם כיצד דריסת מתודות מאפשרת למחלקות יורשות להחליף התנהגות שעברה בירושה במימוש משלהן.
נסו בעצמכם
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// קרא את הקלטים
String message = scanner.nextLine();
String recipient = scanner.nextLine();
// TODO: צור אובייקט Notification עם ההודעה
// TODO: צור אובייקט EmailNotification עם ההודעה והנמען
// TODO: קרא ל-send() על אובייקט Notification
// TODO: קרא ל-send() על אובייקט EmailNotification
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות התכנות מונחה העצמים
קבצים חיצונייםמבוא לתכנות מונחה עצמיםמחלקות לעומת אובייקטיםמילת המפתח thisמתודותשדות (מאפיינים)מתודת הבנאיהעמסת בנאיםחזרה – מחשבון פשוט4ירושה
ירושה בסיסית (extends)מילת המפתח superדריסת מתודות (@Override)שרשור בנאיםהמחלקה Objectירושה יחידה ורב־רמתיתלמה אין ירושה מרובה של מחלקותסיכום – היררכיית עובדים7מתודות מיוחדות ומחלקת Object
מתודת toString()equals() ו-hashCode()מתודת clone()compareTo() ו-Comparableהממשק Comparatorסיכום – מיון מותאם אישית2מצייני גישה ואנקפסולציה
סקירה של רמות הגישהמתודות Getter ו-Setterהסתרת מידעמילת המפתח finalסיכום – מנהל חשבון בנק5פולימורפיזם
יסודות העמסת מתודותדריסת מתודות (בזמן ריצה)המרה כלפי מעלה וכלפי מטההאופרטור instanceofמחלקות ומתודות מופשטותסיכום – מחשבון צורות8מושגי OOP מתקדמים
הרכבה מול ירושהאגרגציה מול הרכבהמחלקות פנימיות, מקוננות ואנונימיותEnums ומתודות של EnumRecords (Java 16+)מחלקות חתומות (Java 17+)3מאפייני מחלקה וחברים סטטיים
משתני מופע לעומת משתנים סטטייםמתודות סטטיותבלוקים סטטייםקבועים (static final)סיכום — מונה ומחלקת עזר6ממשקים ומחלקות מופשטות
מבוא לממשקיםמימוש ממשקיםמימוש של כמה ממשקיםמתודות ברירת מחדל וסטטיות בממשקמחלקות מופשטות לעומת ממשקיםממשקים פונקציונלייםסיכום – מערכת תשלומיםתרגלו בעצמכם: קומפיילר Java אונליין