في CodeGym، يتم تعريف الطلاب بهذه الكلمة الأساسية لـ Java حرفيًا من الدروس الأولى. مع مرور الوقت، يصبح معناها واضحا. لكن بالنظر إلى الوراء، ربما يعترف العديد من الأشخاص لأنفسهم أنهم لم يتمكنوا من فهم Zen لهذه الكلمة الرئيسية لفترة طويلة. ستعمل هذه المقالة على كشف الستار عن أسرار الكلمة الأساسية هذه لأي شخص لم يتمكن من فعل ذلك بعد... لقد حصلت على مرجع Java الخاص بـSchildt
، ثم في الصفحة 171 يمكنك أن ترى أن هذه الكلمة الأساسية مطلوب لطريقة للإشارة إلى الكائن الذي يطلق عليه. يمكننا أن ننهي الدرس بذلك. لكننا بحاجة إلى تفاصيل. كقاعدة عامة، تحتاج إلى استخدام هذا في حالتين:
- عندما يكون لمتغير مثيل ومتغير الطريقة/المنشئ نفس الاسم؛
- عندما تحتاج إلى استدعاء نوع معين من المُنشئ (على سبيل المثال، مُنشئ افتراضي أو مُنشئ ذو معلمات) من نوع آخر من المُنشئ. وهذا ما يسمى أيضًا استدعاء منشئ صريح.
مثال 1: متغير المثيل ومتغير الأسلوب لهما نفس الاسم.
لنفترض أن لدينا فئة Human التي تحدد حقل الاسم: فلنقم بإنشاء أداة ضبط لمتغير الاسم (أداة الضبط تعمل بكامل طاقتها - لا توجد مشكلة هنا):class Human {
String name;
public void setName(String newName) {
name = newName;
}
}
لاحظ أننا قمنا بتمرير String newName إلى طريقة ضبط setName . لقد أعلنا عن متغير جديد وكان بإمكاننا تسميته بما نريد لأنه سيكون مرئيًا فقط داخل الأقواس المتعرجة ({}) التي تحيط بطريقة setName . لاحظ أن أداة الضبط تحتوي على سطر واحد:
name = newName;
لقد قدمنا هنا متغيرًا جديدًا يسمى newName وقمنا بتعيينه لمتغير الاسم الموجود للكائن . قد يجد العديد من المبرمجين أنه من الغريب تقديم متغير باسم جديد عندما نتحدث في النهاية عن نفس الشيء. أي أننا نتحدث عن حقل الاسم في فئة الإنسان . ولهذا السبب فكر منشئو Java في طريقة لاستخدام نفس اسم المتغير بشكل ملائم. وبعبارة أخرى، لماذا يكون هناك اسمان للمتغير يدلان على نفس الشيء. وبعبارة أخرى، نريد أن نفعل شيئا مثل هذا:
class Human {
String name;
public void setName(String name) {
name = name;
}
}
ولكن هنا نواجه مشكلة . لدينا الآن متغيرين بنفس الاسم. ينتمي اسم سلسلة واحدة إلى فئة Human ، بينما ينتمي اسم السلسلة الآخر إلى طريقة setName الخاصة به . ونتيجة لذلك، لن يعرف JVM المتغير الذي تشير إليه عندما تكتب السطر التالي في أداة الضبط:
name = name;
تفترض Java أنك تقصد أقرب متغير اسم ، أي المتغير من طريقة setName : لذلك اتضح أنك تقوم ببساطة بتعيين متغير اسم الطريقة لنفسها. وهذا بالطبع لا معنى له. لذلك، تحتاج اللغة إلى طريقة ما لتمييز متغير اسم الفئة البشرية عن متغير الاسم في طريقة setName . تم حل هذه المشكلة عن طريق إدخال الكلمة الأساسية this ، والتي تشير في هذه الحالة إلى أنك تنوي الإشارة إلى المتغير المرتبط بمثيل للفئة Human ، وليس المتغير في الطريقة: بمعنى آخر، يشير هذا إلى الكائن المستدعي، كما ذكرنا في بداية المقال. ونتيجة لذلك، يقوم الأسلوب setName بتعيين اسم الشخص على الكائن الذي تم إنشاؤه. يوجد أدناه رمز البرنامج دون استخدام الكلمة الأساسية هذه . يقوم الكود بإنشاء كائن بشري ويعين له اسمًا: وإليك الكود الذي يحتوي على الكلمة الأساسية هذه :
public class Solution {
public static void main(String[] args) {
Human human1 = new Human();
human1.setName("Vinny");
human1.print();
}
}
class Human {
String name;
public String getName() {
return name;
}
public void setName(String name){
this.name = name;
}
void print() {
System.out.println(name);
}
}
وبالتالي، يتيح لنا هذا تجنب إدخال متغيرات جديدة للإشارة إلى نفس الشيء، مما يجعل الكود أكثر نظافة وأقل ازدحامًا بالمتغيرات الإضافية.
مثال 2: استخدام هذا لاستدعاء منشئ صريح
يمكن أن يكون استدعاء مُنشئ واحد من مُنشئ آخر مفيدًا عندما يكون لديك (بشكل غريب) مُنشئات متعددة ولا ترغب في أن يقوم المُنشئ الجديد بتكرار رمز التهيئة المكتوب مسبقًا في مُنشئ مختلف. مشوش؟ انها ليست مخيفة جدا كما يبدو. انظر إلى الكود أدناه. لديها اثنين من المنشئين للفئة البشرية :class Human {
int age;
int weight;
int height;
Human(int age, int weight) {
this.age = age;
this.weight = weight;
}
Human(int age, int weight, int height) {
// Call the constructor with two parameters
this(age, weight);
// and then initialize the missing variable
this.height = height;
}
}
لقد قمنا هنا أولاً بتوفير مُنشئ بمعلمتين: int age و intweight . لنفترض أنه يحتوي على سطرين من التعليمات البرمجية:
this.age = age;
this.weight = weight;
لاحقًا، قررنا إضافة مُنشئ آخر بثلاثة معلمات، مع إضافة الارتفاع إلى معلمات العمر والوزن الموجودة. يمكنك كتابة المنشئ الجديد مثل هذا:
this.age = age;
this.weight = weight;
this.height = height;
ولكن بدلاً من تكرار التعليمات البرمجية الموجودة في هذا المنشئ، يمكنك استخدام الكلمة الأساسية this لاستدعاء المنشئ بشكل صريح باستخدام معلمتين:
this(age, weight);
// and then initialize the missing variable:
this.height = height;
يبدو الأمر كما لو أننا نقول للمنشئ ثلاثي المعلمات:
- استدعاء هذا المنشئ الآخر الذي يحتوي على معلمتين
- ثم قم بإضافة متغير آخر.
GO TO FULL VERSION