البرمجة

المتغيران this و super في جافا

المتغيران الخاصان this و super في جافا: شرح موسع وشامل

في لغة البرمجة جافا، تُعتبر الكلمتان المفتاحيتان this و super من المفاهيم الأساسية التي يحتاج المبرمج إلى فهمها بعمق، خصوصًا عند التعامل مع البرمجة الكائنية التوجه (OOP). تلعب هاتان الكلمتان دورًا محوريًا في كيفية إدارة الكائنات، الوصول إلى المتغيرات، والوظائف داخل الطبقات (Classes)، وبناء علاقات الوراثة بين الكائنات والطبقات المختلفة.

في هذا المقال، سيتم تناول شرح شامل وموسع لمفهومي this و super في جافا، مع بيان أهميتهما، كيفية استخدامهما، والفرق الجوهري بينهما، مع توضيحات وأمثلة عملية تفصيلية تعزز الفهم.


مفهوم this في جافا

تعريف this

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

تستخدم this بشكل رئيسي للتفرقة بين المتغيرات المحلية للتابع (Method) أو الباني (Constructor) وبين المتغيرات الخاصة بالطبقة (Instance variables) التي قد تحمل نفس الاسم.

أهمية this

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

علاوة على ذلك، تساعد this على:

  • تمرير الكائن الحالي كمعامل لطريقة أو مُنشئ آخر.

  • استدعاء مُنشئات أخرى داخل نفس الطبقة (Constructor Overloading).

  • زيادة وضوح الكود في حالة تعدد المتغيرات ذات الأسماء المتشابهة.

حالات استخدام this

1. التمييز بين المتغيرات المحلية ومتغيرات الطبقة

java
public class Person { private String name; public Person(String name) { this.name = name; // this.name يشير إلى متغير الطبقة، أما name فهو المتغير المحلي } public void printName() { System.out.println(this.name); } }

في المثال أعلاه، المتغير المحلي name في المُنشئ يتداخل اسمه مع المتغير الخاص بالطبقة. لذلك استخدمنا this.name لتوضيح أننا نعني متغير الطبقة وليس المتغير المحلي.

2. تمرير الكائن الحالي كوسيط

يمكن استخدام this لتمرير الكائن الحالي إلى وظيفة أو مُنشئ آخر.

java
public class Button { public void setListener(ClickListener listener) { // ... } public void initialize() { setListener(this); // تمرير الكائن الحالي كوسيط } }

3. استدعاء مُنشئ آخر داخل نفس الطبقة (Constructor Chaining)

يمكن استخدام this() لاستدعاء مُنشئ آخر في نفس الطبقة ضمن المُنشئ الحالي.

java
public class Rectangle { private int width, height; public Rectangle() { this(0, 0); // استدعاء المُنشئ الثاني } public Rectangle(int width, int height) { this.width = width; this.height = height; } }

ملاحظات هامة عن this

  • لا يمكن استخدام this في الدوال الثابتة (static methods) لأن الثابتات لا تتبع كائنًا محددًا بل تتبع الطبقة.

  • يمكن أن تكون this مفيدة جدًا في برمجة الواجهات الرسومية أو في تصميم الأنماط مثل Builder Pattern حيث يتم إعادة الكائن نفسه.


مفهوم super في جافا

تعريف super

الكلمة المفتاحية super تستخدم للإشارة إلى الطبقة الأب (Superclass) للكائن الحالي. وهي أداة تتيح لك الوصول إلى المتغيرات والطرق التي تم تعريفها في الطبقة الأعلى في تسلسل الوراثة.

باختصار، super تستخدم لتجاوز أو توسيع وظائف الطبقة الأصلية، وكذلك لاستدعاء المُنشئات الخاصة بالطبقة الأب.

أهمية super

في الوراثة (Inheritance) التي هي أحد المبادئ الأساسية في البرمجة الكائنية، يتم توريث المتغيرات والأساليب من الطبقة الأم إلى الطبقة الابنة. لكن في بعض الحالات قد يرغب المبرمج في:

  • استدعاء دالة في الطبقة الأب التي تم تجاوزها (Overridden method).

  • الوصول إلى متغيرات الطبقة الأم التي قد تم إخفاؤها (Shadowed) في الطبقة الابنة.

  • استدعاء مُنشئ الطبقة الأب لضمان تهيئة الكائن بشكل صحيح.

حالات استخدام super

1. استدعاء مُنشئ الطبقة الأب

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

java
public class Animal { private String name; public Animal(String name) { this.name = name; } } public class Dog extends Animal { private String breed; public Dog(String name, String breed) { super(name); // استدعاء مُنشئ الطبقة الأب this.breed = breed; } }

في هذا المثال، استخدام super(name) في مُنشئ الطبقة الابنة (Dog) يسمح بتهيئة المتغير name في الطبقة الأب (Animal).

2. استدعاء طريقة من الطبقة الأب تم تجاوزها (Overridden Method)

في حالة تجاوز طريقة في الطبقة الابنة، يمكن استدعاء طريقة الطبقة الأب عبر super.

java
public class Animal { public void sound() { System.out.println("Animal sound"); } } public class Dog extends Animal { @Override public void sound() { super.sound(); // استدعاء طريقة الطبقة الأب System.out.println("Dog barks"); } }

عند استدعاء sound() على كائن من نوع Dog، سيتم طباعة النص الخاص بالطبقة الأب أولاً ثم النص الخاص بالطبقة الابنة.

3. الوصول إلى المتغيرات المخفية في الطبقة الأب

في بعض الأحيان، قد يحمل المتغير اسمًا مطابقًا في الطبقة الابنة والطبقة الأب. عندها يمكن استخدام super للوصول إلى متغير الطبقة الأب.

java
public class Parent { protected int value = 10; } public class Child extends Parent { protected int value = 20; public void printValues() { System.out.println(value); // يطبع 20 (متغير الطبقة الابنة) System.out.println(super.value); // يطبع 10 (متغير الطبقة الأب) } }

الفروق الجوهرية بين this و super

الخاصية this super
يشير إلى الكائن الحالي (الطبقة الابنة) الطبقة الأب للكائن الحالي
الاستخدام الأساسي الوصول إلى المتغيرات والطرق الخاصة بالكائن الحالي الوصول إلى المتغيرات والطرق في الطبقة الأب
استدعاء المُنشئات يستدعي مُنشئات في نفس الطبقة (this()) يستدعي مُنشئات الطبقة الأب (super())
إمكانية استخدامه في static methods لا يمكن استخدامه لا يمكن استخدامه
الغرض تمييز المتغيرات المحلية عن متغيرات الطبقة، وتمرير الكائن الحالي استدعاء وظائف الطبقة الأب وتجاوز الوظائف المتجاوزة

علاقة this و super بالوراثة وتصميم البرمجيات

تعتبر الكلمتان المفتاحيتان this و super أدوات لا غنى عنها عند تصميم هياكل بيانات متقدمة تعتمد على الوراثة والتعددية (Polymorphism). فهم كيفية استخدامهما بشكل صحيح يسهل إدارة الكود ويجعل البرمجيات أكثر مرونة وقابلية للتطوير.

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


تطبيقات عملية متقدمة

استخدام this في نمط تصميم Builder

في نمط التصميم Builder، يُستخدم this لإرجاع الكائن الحالي من داخل طرق الإعداد (Setter methods)، مما يسمح بتسلسل أو ربط استدعاءات الدوال بطريقة مريحة.

java
public class Car { private String model; private String color; public Car setModel(String model) { this.model = model; return this; } public Car setColor(String color) { this.color = color; return this; } public void printDetails() { System.out.println("Model: " + model + ", Color: " + color); } } // الاستخدام Car car = new Car().setModel("Toyota").setColor("Red"); car.printDetails();

استخدام super مع الواجهات الافتراضية (Default Methods)

مع إصدار جافا 8، أُضيفت إمكانية وجود طرق افتراضية داخل الواجهات (Interfaces). في حالات الوراثة المتعددة للواجهات، يمكن استخدام super لاستدعاء تنفيذ محدد لطريقة من واجهة معينة.

java
interface A { default void show() { System.out.println("Interface A"); } } interface B { default void show() { System.out.println("Interface B"); } } public class C implements A, B { public void show() { A.super.show(); // استدعاء طريقة show من الواجهة A B.super.show(); // استدعاء طريقة show من الواجهة B } }

تلخيص ودليل استخدام this و super

الحالة الكلمة المفتاحية المناسبة شرح الاستخدام
الإشارة إلى الكائن الحالي this عند الحاجة للوصول إلى متغيرات أو دوال الطبقة الحالية التي قد تتداخل أسماؤها
استدعاء مُنشئ في نفس الطبقة this() لتفادي تكرار الكود في المُنشئات (Constructor Chaining)
استدعاء مُنشئ الطبقة الأب super() لتهيئة الخصائص الموروثة من الطبقة الأب
استدعاء دالة تم تجاوزها super.methodName() للوصول إلى وظيفة الطبقة الأب المتجاوزة
الوصول إلى متغير مخفي super.variableName للحصول على متغير الطبقة الأب عند وجود متغير بنفس الاسم في الطبقة الابنة

تأثير this و super على أداء البرامج

رغم أن this و super هما مجرد أدوات إشارية للكائنات والطبقات، فإن فهمهما واستخدامهما بشكل صحيح يؤثر بشكل مباشر على جودة ووضوح الكود البرمجي، ويعزز من سهولة صيانته وتطويره. استخدام هذه الكلمتين يقلل الأخطاء البرمجية التي قد تحدث بسبب التداخل في أسماء المتغيرات أو سوء استدعاء الوظائف.

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


المصادر والمراجع

  • Java: The Complete Reference, Herbert Schildt, 11th Edition, McGraw-Hill Education, 2018.

  • Effective Java, Joshua Bloch, 3rd Edition, Addison-Wesley, 2018.


بهذا يتضح أن كلًا من this و super تمثلان أدوات جوهرية وضرورية في برمجة جافا الكائنية التوجه، وتوفران طريقة منظمة وواضحة لإدارة المتغيرات والوظائف ضمن سياق الطبقات والوراثة، مما يجعل الكود أكثر مرونة وقابلية للصيانة والتطوير.