مفهوم الـ Overriding
في الدرس السابق, شاهدت كيف أن الـ Subclass يرث المتغيرات و الدوال الموجودة في الـ Superclass. و تعلمت أيضاً أنه يمكن للـ Subclass إعادة تعريف أي دالة ورثها من الـ Superclass شرط أن لا تكون معرفة كـ final
, و كتابة الكلمة @Override
قبل تعريفها من جديد حتى تتفادى حدوث مشاكل عند ترجمة الكود.
Override: تعني تعريف الدالة التي ورثها الـ Subclass من الـ Superclass من جديد, هذه الدالة الجديدة تكون مشابهة للدالة الموروثة من حيث الشكل فقط, أي لها نفس الإسم و النوع و عدد الباراميترات, لكن محتواها مختلف.
الهدف الحقيقي من الـ Overriding هو إتاحة الفرصة للـ Subclass ليعرف الدوال حسب حاجته.
في دروس متقدمة سنرث من كلاسات جاهزة في جافا, و نفعل Override للدوال الموجودة فيها لكي تناسب التطبيقات التي سنقوم ببنائها.
مثال
الآن لنفترض أننا قمنا بتعريف كلاس إسمه Country
, يحتوي على دالة إسمها language()
.
بعدها قمنا بتعريف ثلاث كلاسات, و كلها ترث من Country
, إذاً كلها ستحتوي على الدالة language()
.
هنا الفكرة أن أي كلاس يرث من Country
قد يضطر إلى تعريف الدالة language()
من جديد حتى تناسبه.
بعد إنشاء هذه الكلاسات, سنقوم بإنشاء الكلاس Main
لتجربتهم.
public class Country { // هنا, هذا الكلاس يعتبر الكلاس الأساسي لأي دولة في العالم, إذاً يجب أن يرثه أي كلاس يمثل دولة public void language() { System.out.println("English"); // هنا قمنا بوضع اللغة الإنجليزية كلغة إفتراضية لجميع البلدان } }
public class Australia extends Country { // من جديد لأن اللغة الإنجليزية هي لغة أستراليا language() هنا لا داعي لتعريف الدالة }
public class Lebanon extends Country { // من جديد لأن اللغة الإنجليزية ليست لغة لبنان language() هنا يجب تعريف الدالة @Override public void language() { System.out.println("Arabic"); } }
public class Spain extends Country { // من جديد لأن اللغة الإنجليزية ليست لغة إسبانيا language() هنا يجب تعريف الدالة @Override public void language() { System.out.println("Spanish"); } }
public class Main { public static void main(String[] args) { // هنا قمنا بإنشاء كائنات من البلدان الثلاثة Australia au = new Australia(); Lebanon lb = new Lebanon(); Spain sp = new Spain(); // لعرض لغة كل بلد language() هنا قمنا باستدعاء الدالة au.language(); lb.language(); sp.language(); } }
سنحصل على النتيجة التالية عند التشغيل.
English Arabic Spanish
أنت الآن فهمت لما قد تحتاج أن تفعل Override. سنقوم الآن بشرح طريقة عمل مترجم جافا عندما فعلت Override للدالة language()
.
إذا عدت للكلاس Lebanon
, ستجد أننا فعلنا Override للدالة language()
. إذاً هنا أصبح الكلاس Lebanon
يملك دالتين إٍسمهما language()
, الأولى هي التي ورثها من الـ Superclass, و الثانية هي التي قمنا بتعريفها عندما فعلنا Override.
بما أن الكلاس Lebanon
يملك دالتين لهما نفس الإسم, النوع و عدد البارامتيرات, كيف عرف أي دالة يختار؟
عندما قمنا بتعريف الدالة language()
من جديد في الـ Subclass, قام المترجم بإخفاء الدالة الأصلية ( دالة الـ Superclass ) و أظهر الدالة الجديدة فقط. بالإضافة إلى أن الكلمة @Override
ضمنت لنا حصول هذا, لأنها تخبر المترجم أنه يوجد عدة دوال إسمهم language()
لكننا نريد هذه الدالة بالتحديد عند استدعائها من هذا الكلاس.
إنتبه: في داخل الكلاس Lebanon
, إذا أردنا إستخدام الدالة language()
الموجودة في الـ Superclass و التي قام المترجم بإخفائها عندما قمنا بتعريفها من جديد, يمكننا ذلك بواسطة الكلمة super
التي شرحناها في الدرس السابق.