0Pricing
Java Academy · درس

قواعد تحميل الأساليب الزائد

افهم كيفية حل Java للأساليب المحمّلة تحميلًا زائدًا ومواطن الالتباس الشائعة

قواعد تحميل الأساليب الزائد درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.

قواعد التحميل الزائد للأساليب

يتيح تحميل الأساليب زائدًا تعريف عدة أساليب بالاسم نفسه، لكن بقوائم معاملات مختلفة. وتختار Java أفضل تطابق وقت الترجمة باستخدام قواعد دقيقة لحل الاستدعاء.

ما التحميل الزائد؟

تشترك الأساليب المحمّلة زائدًا في الاسم، لكنها تختلف في عدد المعاملات أو أنواعها أو ترتيبها. ولا يكفي نوع القيمة المعادة وحده لإجراء التحميل الزائد.

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

    // compile error — same signature, different return type only:
    // long add(int a, int b) { return a + b; }
}

Calculator calc = new Calculator();
System.out.println(calc.add(1, 2));       // 3 (int)
System.out.println(calc.add(1.5, 2.5));   // 4.0 (double)
System.out.println(calc.add(1, 2, 3));    // 6 (3-arg)

الحل: التطابق الأكثر تخصيصًا

تختار Java الأسلوب القابل للتطبيق والأكثر تخصيصًا. وتُجرَّب عمليات التوسيع وautoboxing وvarargs حسب ترتيب الأفضلية.

static void print(int x)    { System.out.println("int: "    + x); }
static void print(long x)   { System.out.println("long: "   + x); }
static void print(Object x) { System.out.println("Object: " + x); }

print(42);       // int: 42 (exact match — most specific)
print(42L);      // long: 42 (exact match)
print(3.14);     // Object: 3.14 (no float match, widening then autoboxing)

التوسيع قبل autoboxing

تفضّل Java توسيع النوع البدائي على تحويله باستخدام autoboxing إلى نوع wrapper. وقد يؤدي ذلك إلى نتائج غير متوقعة.

static void display(long n)    { System.out.println("long: " + n); }
static void display(Integer n) { System.out.println("Integer: " + n); }

int x = 100;
display(x); // long: 100 — widens int to long BEFORE autoboxing to Integer
// This surprises many developers!

static void show(Long n)    { System.out.println("Long"); }
static void show(Integer n) { System.out.println("Integer"); }

// show(100); // compile error — ambiguous! Neither is more specific

غموض المعامل null

قد يؤدي تمرير null إلى أساليب محمّلة زائدًا إلى حدوث غموض إذا كانت عدة أساليب تقبل أنواع مراجع. استخدموا تحويلًا نوعيًا لـ null لحل الغموض.

static void handle(String s)  { System.out.println("String: " + s); }
static void handle(Integer i) { System.out.println("Integer: " + i); }
static void handle(Object o)  { System.out.println("Object"); }

handle((String) null);  // String: null (cast resolves ambiguity)
handle((Integer) null); // Integer: null
// handle(null);        // compile error: ambiguous (String vs Integer)

التحميل الزائد مع الوراثة

يأخذ حل الأسلوب في الاعتبار النوع المعلن لمتغير المرجع، وليس نوعه وقت التشغيل؛ فهذا قرار يُتخذ وقت الترجمة.

class Animal {}
class Dog extends Animal {}

static void greet(Animal a) { System.out.println("Animal"); }
static void greet(Dog d)    { System.out.println("Dog"); }

Animal a = new Dog(); // declared as Animal
greet(a);   // Animal — compile-time type is Animal!

Dog d = new Dog();
greet(d);   // Dog — compile-time type is Dog

التحميل الزائد مقابل إعادة التعريف

التحميل الزائد قرار يُتخذ وقت الترجمة، أي إرسال ثابت. أما إعادة التعريف فهي قرار يُتخذ وقت التشغيل، أي إرسال ديناميكي، استنادًا إلى النوع الفعلي للكائن.

class Base {
    void run() { System.out.println("Base.run"); }
}
class Sub extends Base {
    @Override
    void run() { System.out.println("Sub.run"); } // overriding

    void run(int speed) { System.out.println("Sub.run(" + speed + ")"); } // overloading
}

Base b = new Sub();
b.run();     // Sub.run — override (runtime dispatch)
// b.run(10); // compile error — Base doesn't have run(int)

أنماط التحميل الزائد الشائعة

من الاستخدامات الشائعة للتحميل الزائد في واجهات API توفير أساليب ملائمة تفوّض العمل إلى إصدار يقبل جميع المعاملات.

class Connection {
    void connect(String host, int port, int timeout) {
        System.out.println("Connecting to " + host + ":" + port + " timeout=" + timeout);
    }

    // Convenience overloads
    void connect(String host, int port) {
        connect(host, port, 30); // delegate with default timeout
    }

    void connect(String host) {
        connect(host, 5432); // delegate with default port
    }
}

new Connection().connect("db.example.com");
// Connecting to db.example.com:5432 timeout=30

التحميل الزائد والأنواع العامة

يتطلب تحميل الأساليب العامة زائدًا عناية، إذ قد يجعل محو الأنواع توقيعين يبدوان مختلفين متطابقين بعد الترجمة.

// Type erasure problem: both methods erase to the same signature!
// static void process(List<String> list) {} // compile error
// static void process(List<Integer> list) {} // duplicate after erasure

// Solutions:
// 1. Use different method names: processStrings / processIntegers
// 2. Use a generic method with bounded type:
static <T extends Number> void processNumbers(List<T> list) {
    list.forEach(n -> System.out.println(n.doubleValue()));
}
processNumbers(List.of(1, 2, 3));
processNumbers(List.of(1.5, 2.5));

تطبيق عملي: تحميل زائد بأسلوب Builder

ينتشر التحميل الزائد في واجهات Builder وfactory API لتوفير إنشاء مرن للكائنات.

class Notification {
    final String title, body;
    final String imageUrl;
    final boolean urgent;

    // Factory overloads for convenience
    static Notification simple(String title, String body) {
        return new Notification(title, body, null, false);
    }
    static Notification urgent(String title, String body) {
        return new Notification(title, body, null, true);
    }
    static Notification withImage(String title, String body, String url) {
        return new Notification(title, body, url, false);
    }
    Notification(String title, String body, String imageUrl, boolean urgent) {
        this.title = title; this.body = body;
        this.imageUrl = imageUrl; this.urgent = urgent;
    }
}

مطبات التحميل الزائد

تجنبوا أخطاء التحميل الزائد الشائعة التالية:

  • كثرة الإصدارات المحمّلة زائدًا للعملية نفسها؛ استخدموا Builder بدلًا من ذلك
  • إصدارات تختلف فقط في ترتيب المعاملات؛ فهذا يسبب الالتباس
  • التوسيع غير المتوقع: قد يُحل int إلى long بدلًا من Integer
// Confusing: order-based overloads
// void save(String name, int age)  {}
// void save(int age, String name)  {} // very confusing!

// Better: use a record/DTO
record UserData(String name, int age) {}
void save(UserData data) {}

// Surprising widening
static void m(long x)   { System.out.println("long"); }
static void m(Integer x){ System.out.println("Integer"); }
int v = 5;
m(v); // long! widening preferred over autoboxing

تحقق سريع

إذا كان هناك تحميل زائد لأسلوب بمعاملات من النوعين long وInteger، فأيٌّ منهما يُختار عند تمرير وسيطة من النوع int؟

مراجعة: قواعد التحميل الزائد للأساليب

أهم النقاط:

  • يختلف التحميل الزائد باختلاف عدد المعاملات أو أنواعها أو ترتيبها — وليس بنوع القيمة المُعادة وحده
  • تحل Java التحميل الزائد وقت الترجمة باستخدام النوع المُعلن للوسائط
  • يُفضَّل توسيع النوع البدائي على تحويله تلقائيًا إلى نوع مغلف
  • قد تسبب الوسائط التي قيمتها null غموضًا — استخدم التحويل لتحديد المقصود: handle((String) null)
  • يحدث التحميل الزائد وقت الترجمة، بينما تحدث إعادة التعريف وقت التشغيل — وهما آليتان مختلفتان
  • استخدم أساليب التحميل الزائد الميسِّرة التي تفوِّض التنفيذ إلى أسلوب رئيسي يستقبل جميع المعاملات

الأسئلة الشائعة

هل درس «قواعد تحميل الأساليب الزائد» مجاني؟

نعم — نص درس «قواعد تحميل الأساليب الزائد» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.

ماذا ستتعلم في «قواعد تحميل الأساليب الزائد»؟

افهم كيفية حل Java للأساليب المحمّلة تحميلًا زائدًا ومواطن الالتباس الشائعة تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟

لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «قواعد تحميل الأساليب الزائد»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟

نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. قواعد تحميل الأساليب الزائد
  2. معاملات Varargs
  3. الحقول والثوابت الثابتة
  4. فئات الأدوات وأساليب المصنع الثابتة
← العودة إلى Java Academy