Method overloading Vs. method overriding

ההבדל המרכזי בין Method Overloading לבין Method Overriding טמון בזמן שבו המערכת מחליטה איזו מתודה להפעיל, ובקשר המשפחתי הנדרש בין המחלקות.

Method Overloading

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

מטרה: לאפשר לאותה פעולה להתבצע בצורות שונות בהתאם לנתונים שמועברים אליה (למשל, מתודת add שיכולה לחבר שני מספרים שלמים, שלושה מספרים, או מספרים עשרוניים).

זמן החלטה (Binding): מתרחש בזמן הקומפילציה (Compile-time polymorphism / Static binding). הקומפיילר יודע בדיוק באיזו מתודה להשתמש לפי הפרמטרים ששלחנו.

כללים מרכזיים:

דוגמת קוד ל-Overloading:

public class MathUtils {

    // Overloaded method taking two integers
    public int add(int a, int b) {
        return a + b;
    }

    // Overloaded method taking three integers
    public int add(int a, int b, int c) {
        return a + b + c;
    }

    // Overloaded method taking double values
    public double add(double a, double b) {
        return a + b;
    }
}

Method Overriding

דריסה מתרחשת כאשר מחלקת-בת (Subclass) מספקת מימוש משל עצמה למתודה שכבר קיימת במחלקת האב (Superclass) או בממשק, בדיוק באותה חתימה.

מטרה: לאפשר למחלקת הבת לשנות או להתאים את ההתנהגות של מחלקת האב לצרכים הייחודיים שלה (למשל, מחלקת Animal מגדירה ()makeSound, ומחלקת Cat דורסת אותה כדי לעשות "Meow").

זמן החלטה (Binding): מתרחש בזמן ריצה (Runtime polymorphism / Dynamic Dispatch). המערכת מסתכלת על סוג האובייקט האמיתי שנמצא ב-Heap (ולא על סוג הטיפוס ב-Stack) ומחליטה איזו מתודה להפעיל.

כללים מרכזיים:

דוגמת קוד ל-Overriding:

class Animal {
    // Parent class method
    public void makeSound() {
        System.out.println("Animal makes a general sound");
    }
}

class Cat extends Animal {
    // Overriding the parent method
    @Override
    public void makeSound() {
        System.out.println("Cat says: Meow Meow");
    }
}

טבלת השוואה מהירה

תכונה Method Overloading Method Overriding
מיקום הקוד באותה מחלקה (או דרך ירושה באותה משפחה). חייב להיות בשתי מחלקות שונות הקשורות בירושה (אב ובן).
חתימת פרמטרים חייבת להיות שונה (כדי שהקומפיילר יבדיל ביניהן). חייבת להיות זהה לחלוטין.
זמן החלטה Compile-time (סטטי). Runtime (דינמי / Dynamic Dispatch).
סוג הערך המחזיר יכול להיות שונה או זהה. חייב להיות זהה (או תת-טיפוס תואם - Covariant return type).
מנגנון פולימורפיזם Static Polymorphism Dynamic Polymorphism

Dynamic Polymorphism (פולימורפיזם דינמי / Runtime Polymorphism)

פולימורפיזם דינמי מתרחש בזמן ריצת התוכנית (Runtime). במצב זה, הקומפיילר בזמן ההידור עדיין לא יודע בדיוק איזה קוד יורץ, וההחלטה מתקבלת רק כשהאפליקציה פועלת בפועל מול האובייקטים שבזיכרון (ה-Heap).

איך זה בא לידי ביטוי? זה מתבצע באמצעות Method Overriding בשילוב עם ירושה או מימוש ממשקים, כאשר משתמשים במשתנה מטיפוס אב (או interface) שמצביע על אובייקט של מחלקה בת.

איך המערכת מחליטה? התוכנית "מסתכלת" על סוג האובייקט האמיתי שיושב ב-Heap (ולא על הטיפוס שמוגדר ב-Stack). בעזרת מנגנון שנקרא Dynamic Method Dispatch (או Late Binding), המערכת נעזרת בטבלת וירטואלית (vtable) כדי לשלוף את המתודה המעודכנת ביותר של האובייקט הספציפי בזמן אמת.

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

Static Polymorphism (פולימורפיזם סטטי / Compile-Time Polymorphism)

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

איך זה בא לידי ביטוי? זה קורה בעיקר באמצעות Method Overloading (העמסת מתודות) שאפשרה לנו להשתמש באותו שם מתודה עם פרמטרים שונים, או דרך מתודות סטטיות (static methods).

איך המערכת מחליטה? הקומפיילר בוחן את חתימת המתודה ואת סוגי המשתנים ששלחנו לה ברגע כתיבת הקוד. לפי סוג הנתונים המועברים בסוגריים הוא "מדביק" את הכתובת המדויקת של המתודה לקוד (תהליך שנקרא Early Binding או Static Binding).

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

🏠 Back to Orly's Code Corner