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

المُنشئات في جافا: تهيئة الكائنات باستخدام new

كيف تعمل المُنشئات في جافا: المُنشئ الافتراضي، والمُنشئات ذات المعاملات، وthis، وتحميل المُنشئات الزائد، والتسلسل باستخدام this() وsuper().

تحتوي هذه الصفحة على محررات قابلة للتشغيل - حرّر، شغّل، وشاهد النتيجة فوراً.

لماذا توجد المُنشئات

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

يبدو المُنشئ كـالدالة، لكن مع فرقين: يحمل الاسم نفسه الذي تحمله الفئة، وليس له أي نوع إرجاع، ولا حتى void.

يقوم new Point(3, 4) بتخصيص الكائن ثم يُنفّذ جسم المُنشئ بقيم x = 3 وy = 4. وبحلول الوقت الذي يعود فيه new، يكون p قد تمت تهيئته بالكامل.

الكلمة المفتاحية this

داخل المُنشئ أعلاه، سُمّيت المعاملات x وy، وهي الأسماء نفسها التي تحملها الحقول. تعني this.x "الحقل x الذي يخص هذا الكائن"، بينما تشير x المجردة إلى المعامل. من دون this، فإن x = x ستُسند المعامل إلى نفسه فحسب وتترك الحقل دون تغيير.

أنت بحاجة إلى this فقط عندما يحجب معاملٌ حقلًا، لكن كثيرين يستخدمونه في كل مكان من باب الوضوح. الخطأ الشائع هو نسيانه عند تطابق الأسماء: يُترجَم الكود ويُنفَّذ، ويترك حقولك بصمت على قيمها الافتراضية (null و0 وfalse).

المُنشئ الافتراضي

إذا لم تكتب مُنشئًا أبدًا، توفّر جافا بهدوء مُنشئًا افتراضيًا: مُنشئ عام (public) بلا وسائط لا يفعل شيئًا إضافيًا. لهذا السبب كان new يعمل على الفئات التي لم يكن لها أي مُنشئ على الإطلاق.

المشكلة الخفية: بمجرد أن تكتب أي مُنشئ، يختفي المُنشئ المجاني.

class Box {
    int size;

    Box(int size) {       // الآن لا يوجد مُنشئ بلا وسائط
        this.size = size;
    }
}

new Box();   // خطأ في الترجمة: المُنشئ Box() غير موجود

إذا كنت لا تزال تريد أن يعمل new Box()، فصرّح بالمُنشئ الذي لا يأخذ وسائط بنفسك:

تحميل المُنشئات الزائد

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

تختار جافا المُنشئ المطابق بناءً على عدد الوسائط التي تمررها إلى new وأنواعها.

التسلسل باستخدام this()

لاحظ التكرار أعلاه: كل مُنشئ يُسند الحقول بنفسه. يمكنك تجنّب ذلك بجعل أحد المُنشئات يستدعي آخر باستخدام this(...). يجب أن يكون هذا الاستدعاء العبارة الأولى في المُنشئ.

الآن أصبحت التهيئة الفعلية في مكان واحد. أما المُنشئات الأصغر فلا تفعل سوى ملء القيم الافتراضية وتمرير العمل. وإذا حاولت يومًا وضع عبارة قبل this(...)، فسيرفضها المُترجم.

المُنشئات وsuper()

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

class Animal {
    String name;
    Animal(String name) { this.name = name; }
}

class Dog extends Animal {
    Dog(String name) {
        super(name);   // يجب هنا استدعاء مُنشئ الأب صراحةً
    }
}

بما أن Animal ليس لها مُنشئ بلا وسائط، فإن Dog يجب أن تستدعي super(name) صراحةً، إذ لا يوجد super() مجاني تلجأ إليه. وكما هو الحال مع this()، يجب أن يكون استدعاء super(...) العبارة الأولى في المُنشئ.

التالي: الوراثة

تُهيّئ المُنشئات كائنًا واحدًا، لكن super() لمّحت بالفعل إلى شيء أكبر: يمكن للفئات أن تُبنى على فئات أخرى، فتعيد استخدام حقولها ودوالها ومُنشئاتها. تلك العلاقة، أي امتداد فئة لأخرى، هي الوراثة، وهي موضوع الصفحة التالية.

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

ما هو المُنشئ (constructor) في جافا؟

المُنشئ هو دالة خاصة تُنفَّذ عند إنشاء كائن باستخدام new. يحمل الاسم نفسه الذي تحمله الفئة وليس له نوع إرجاع (ولا حتى void). مهمته هي وضع الكائن الجديد في حالة بداية صالحة، وعادةً ما يتم ذلك بإسناد معاملات المُنشئ إلى حقول الكائن.

ما الفرق بين المُنشئ والدالة في جافا؟

المُنشئ يحمل الاسم نفسه تمامًا الذي تحمله الفئة، ولا يُصرّح بأي نوع إرجاع، ولا يمكن استدعاؤه إلا باستخدام new عند إنشاء كائن. أما الدالة العادية فلها اسمها الخاص، وتُصرّح بنوع إرجاع (أو void)، وتُستدعى على كائن موجود مسبقًا. المُنشئات تُهيّئ؛ والدوال تؤدي العمل بعد ذلك.

ماذا يحدث إذا لم أكتب مُنشئًا في جافا؟

يمنحك المُترجم مجانًا مُنشئًا افتراضيًا بلا معاملات، لا يأخذ أي وسائط ولا يفعل شيئًا سوى الاستدعاء الضمني لـ super(). لكن في اللحظة التي تكتب فيها أي مُنشئ بنفسك، يختفي ذلك المُنشئ المجاني؛ لذا إذا أضفت مُنشئًا ذا معاملات وما زلت تريد أن يعمل new Thing()، فعليك أن تُصرّح صراحةً بالمُنشئ الذي لا يأخذ وسائط.

Coddy programming languages illustration

تعلّم البرمجة مع Coddy

ابدأ الآن