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

تسلسل المنشئات (Constructor Chaining)

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

تسلسل المنشئات (Constructor chaining) هو عملية استدعاء منشئ من منشئ آخر. تساعد هذه التقنية في تجنب تكرار الكود عندما يحتوي الصنف (class) على منشئات متعددة أو عند العمل مع هياكل الوراثة (inheritance hierarchies).

داخل نفس الكلاس، يمكنك ربط المشيدات باستخدام this(). يتيح لك هذا الحصول على مشيد "رئيسي" واحد يقوم بكل العمل، بينما تقوم المشيدات الأخرى ببساطة بالتفويض إليه:

public class Rectangle {
    private int width;
    private int height;
    
    public Rectangle() {
        this(1, 1);  // يستدعي المنشئ الذي يأخذ معاملين
    }
    
    public Rectangle(int size) {
        this(size, size);  // ينشئ مربعاً
    }
    
    public Rectangle(int width, int height) {
        this.width = width;
        this.height = height;
    }
}

في الوراثة، يحدث تسلسل المنشئات (constructor chaining) تلقائيًا. عندما تقوم بإنشاء كائن من فئة فرعية (subclass)، يستدعي Java منشئ الفئة الأب أولاً باستخدام super(). إذا لم تقم باستدعاء super() صراحةً، يقوم Java بإدراج super() (النسخة التي لا تحتوي على وسائط) تلقائيًا:

public class Animal {
    private String name;
    
    public Animal(String name) {
        this.name = name;
        System.out.println("Animal constructor");
    }
}

public class Dog extends Animal {
    private String breed;
    
    public Dog(String name, String breed) {
        super(name);  // يجب أن يكون السطر الأول
        this.breed = breed;
        System.out.println("Dog constructor");
    }
}

إنشاء new Dog("Buddy", "Labrador") يطبع "Animal constructor" أولاً، ثم "Dog constructor". يضمن ذلك تهيئة الفئات الأب (parent classes) بشكل صحيح دائماً قبل أن تضيف الفئة الابن (child class) إعداداتها الخاصة.

challenge icon

التحدي

سهل

لنقم ببناء نظام لطلب المنتجات يوضح تسلسل الاستدعاء للمنشئات (constructor chaining) داخل الفئة الواحدة وعبر تسلسل الوراثة. ستتعلم كيف يقوم this() بربط المنشئات في نفس الفئة، بينما يقوم super() بالربط بمنشئات الفئة الأب.

ستقوم بإنشاء ثلاثة ملفات لتنظيم الكود الخاص بك:

  • Product.java: أنشئ فئة أب تمثل أي منتج في المتجر. يجب أن تحتوي على:
    • حقول خاصة (Private fields) لـ name (String) و price (double)
    • منشئ رئيسي يأخذ كلاً من الاسم والسعر، ويقوم بتهيئة الحقول، ويطبع: Product constructor: [name]
    • منشئ ثانٍ يأخذ الاسم فقط ويقوم بالربط بالمنشئ الرئيسي باستخدام this(name, 0.0) لتعيين سعر افتراضي قدره 0.0
    • دوال getName() و getPrice() للوصول إلى الحقول
  • Electronics.java: أنشئ فئة فرعية (subclass) ترث من Product وتضيف معلومات الضمان:
    • حقل خاص لـ warrantyYears (int)
    • منشئ رئيسي يأخذ الاسم، والسعر، و warrantyYears - استخدم super(name, price) لتهيئة الفئة الأب، ثم قم بتعيين الضمان واطبع: Electronics constructor: [warrantyYears] year warranty
    • منشئ ثانٍ يأخذ الاسم والسعر فقط، ويقوم بالربط بالمنشئ الرئيسي باستخدام this(name, price, 1) لتوفير ضمان افتراضي لمدة عام واحد
    • منشئ ثالث يأخذ الاسم فقط، ويقوم بالربط بالمنشئ الثاني باستخدام this(name, 0.0)
    • دالة getDetails() تعيد: [name] - $[price] ([warrantyYears] year warranty)
  • Main.java: استعرض تسلسل استدعاء المنشئات أثناء العمل. ستتلقى ثلاثة مدخلات: اسم المنتج (String)، والسعر (double)، وسنوات الضمان (int). أنشئ كائن Electronics باستخدام المعاملات الثلاثة، ثم اطبع نتيجة getDetails().

ستتلقى ثلاثة مدخلات: اسم المنتج، والسعر، وسنوات الضمان.

قم بتنسيق السعر في getDetails() ليظهر بمنزلتين عشريتين باستخدام String.format("%.2f", price). راقب المخرجات بعناية - سترى رسائل المنشئات تظهر بالترتيب، مما يوضح كيف يتدفق التسلسل من الأب إلى الابن!

ورقة مرجعية

تسلسل المنشئات (Constructor chaining) هو عملية استدعاء منشئ من منشئ آخر لتجنب تكرار الكود.

التسلسل داخل نفس الفئة

استخدم this() لاستدعاء منشئ آخر في نفس الفئة:

public class Rectangle {
    private int width;
    private int height;
    
    public Rectangle() {
        this(1, 1);  // Calls the two-parameter constructor
    }
    
    public Rectangle(int size) {
        this(size, size);  // Creates a square
    }
    
    public Rectangle(int width, int height) {
        this.width = width;
        this.height = height;
    }
}

التسلسل في الوراثة

استخدم super() لاستدعاء منشئ الفئة الأب. يجب أن يكون السطر الأول في المنشئ:

public class Animal {
    private String name;
    
    public Animal(String name) {
        this.name = name;
        System.out.println("Animal constructor");
    }
}

public class Dog extends Animal {
    private String breed;
    
    public Dog(String name, String breed) {
        super(name);  // Must be first line
        this.breed = breed;
        System.out.println("Dog constructor");
    }
}

إذا لم تقم باستدعاء super() صراحةً، فإن Java تقوم تلقائيًا بإدراج super() (النسخة التي لا تحتوي على وسائط). يتم دائمًا استدعاء منشئات الفئة الأب قبل منشئات الفئة الابن، مما يضمن ترتيب التهيئة الصحيح.

جرّب بنفسك

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // قراءة المدخلات
        String name = scanner.nextLine();
        double price = scanner.nextDouble();
        int warrantyYears = scanner.nextInt();
        
        // TODO: إنشاء كائن Electronics باستخدام جميع المعاملات الثلاثة
        
        // TODO: طباعة نتيجة getDetails()
    }
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming