Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

أساسيات الـ Method Overloading

جزء من قسم Object Oriented Programming في رحلة Java على Coddy — الدرس 28 من 87.

تعني كلمة Polymorphism "أشكالاً متعددة". في لغة Java، يتيح ذلك للكائنات التصرف بشكل مختلف بناءً على السياق. أحد أشكال تعدد الأشكال هو method overloading، ويُسمى أيضاً تعدد الأشكال في وقت التصريف (compile-time polymorphism) لأن Java تحدد الطريقة التي سيتم استدعاؤها أثناء عملية التصريف (compilation).

يتيح لك تحميل الميثود الزائد (Method overloading) تعريف عدة ميثودات بنفس الاسم ولكن بمعاملات مختلفة. يميز المترجم (compiler) بينها بناءً على عدد المعاملات أو نوعها أو ترتيبها:

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
    
    public int add(int a, int b, int c) {
        return a + b + c;
    }
    
    public double add(double a, double b) {
        return a + b;
    }
}

عندما تستدعي add(5, 3)، تستخدم Java الطريقة الأولى. استدعاء add(5, 3, 2) يُفعل الثانية، و add(5.0, 3.0) يستدعي الثالثة. يختار المترجم (compiler) الإصدار الصحيح بناءً على الوسائط (arguments) التي تقدمها.

لاحظ أن تغيير نوع الإرجاع فقط ليس تحميلاً زائداً (overloading) صالحاً. يجب أن تختلف قائمة المعاملات:

// ليس تحميلاً زائداً صالحاً - لن يتم التجميع
public int getValue() { return 1; }
public double getValue() { return 1.0; }  // خطأ!

لقد رأيت التحميل الزائد (overloading) بالفعل من قبل مع التحميل الزائد للمنشئ (constructor overloading). يتبع التحميل الزائد للدوال (Method overloading) نفس القواعد ويوفر المرونة من خلال السماح لاسم دالة واحد بالتعامل مع سيناريوهات إدخال مختلفة.

challenge icon

التحدي

سهل

لنقم ببناء منسق رسائل (message formatter) يوضح مفهوم زيادة تحميل الدوال (method overloading) من خلال توفير طرق متعددة لتنسيق الرسائل. ستقوم بإنشاء فئة أدوات (utility class) تحتوي على عدة دوال format محملة بشكل زائد تتعامل مع سيناريوهات إدخال مختلفة.

ستقوم بتنظيم الكود الخاص بك عبر ملفين:

  • MessageFormatter.java: قم بإنشاء فئة توفر تنسيقاً مرناً للرسائل من خلال الدوال المحملة بشكل زائد. يجب أن يحتوي المنسق الخاص بك على:
    • دالة format(String message) تعيد الرسالة محاطة بأقواس مربعة: [message]
    • دالة format(String message, int repeatCount) تعيد الرسالة مكررة لعدد المرات المحدد، مفصولة بمسافات
    • دالة format(String message, String prefix) تعيد الرسالة مع البادئة المرفقة: prefix: message
    • دالة format(String message, String prefix, String suffix) تعيد: prefix: message (suffix)
    سيختار المترجم (compiler) الدالة الصحيحة بناءً على الوسائط التي تمررها - وهذا هو تعدد الأشكال في وقت التجميع (compile-time polymorphism) قيد التنفيذ!
  • Main.java: قم باستعراض عمل جميع الدوال الأربع المحملة بشكل زائد معاً. ستتلقى أربعة مدخلات: رسالة (String)، وعدد التكرار (int)، وبادئة (String)، ولاحقة (String). قم بإنشاء كائن MessageFormatter واستدعاء كل إصدار من دالة format، مع طباعة كل نتيجة في سطر مستقل:
    • أولاً، التنسيق باستخدام الرسالة فقط
    • ثانياً، التنسيق باستخدام الرسالة وعدد التكرار
    • ثالثاً، التنسيق باستخدام الرسالة والبادئة
    • رابعاً، التنسيق باستخدام الرسالة والبادئة واللاحقة

ستتلقى أربعة مدخلات: نص الرسالة، عدد مرات تكرارها، سلسلة البادئة، وسلسلة اللاحقة.

على سبيل المثال، إذا كانت الرسالة هي "Hello"، وعدد التكرار هو 3، والبادئة هي "INFO"، واللاحقة هي "done"، فيجب أن يظهر مخرجك أربعة إصدارات منسقة مختلفة لنفس الرسالة، كل منها يستخدم دالة محملة بشكل زائد مختلفة!

ورقة مرجعية

يسمح لك التحميل الزائد للدوال (Method overloading) بتعريف عدة دوال بنفس الاسم ولكن بمعاملات مختلفة. يُطلق على هذا أيضًا اسم تعدد الأشكال في وقت التجميع (compile-time polymorphism) لأن لغة Java تحدد الدالة التي سيتم استدعاؤها أثناء عملية التجميع.

يميز المترجم (compiler) بين الدوال المحملة بشكل زائد بناءً على عدد المعاملات أو نوعها أو ترتيبها:

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
    
    public int add(int a, int b, int c) {
        return a + b + c;
    }
    
    public double add(double a, double b) {
        return a + b;
    }
}

عند استدعاء add(5, 3)، تستخدم Java الدالة الأولى. واستدعاء add(5, 3, 2) يشغل الثانية، بينما add(5.0, 3.0) يستدعي الثالثة.

هام: تغيير نوع الإرجاع فقط لا يعتبر تحميلاً زائداً صالحاً. يجب أن تختلف قائمة المعاملات:

// ليس تحميلاً زائداً صالحاً
public int getValue() { return 1; }
public double getValue() { return 1.0; }  // Error!

جرّب بنفسك

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // قراءة المدخلات
        String message = scanner.nextLine();
        int repeatCount = Integer.parseInt(scanner.nextLine());
        String prefix = scanner.nextLine();
        String suffix = scanner.nextLine();
        
        // TODO: إنشاء كائن MessageFormatter
        
        // TODO: استدعاء format مع message فقط وطباعة النتيجة
        
        // TODO: استدعاء format مع message و repeatCount وطباعة النتيجة
        
        // TODO: استدعاء format مع message و prefix وطباعة النتيجة
        
        // TODO: استدعاء format مع message و prefix و suffix وطباعة النتيجة
        
    }
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Object Oriented Programming