Animal
التي تشير إلى الحيوانات وننشئ طريقة فيها voice
- " الصوت ":
public class Animal {
public void voice() {
System.out.println("Voice!");
}
}
على الرغم من أننا بدأنا للتو في كتابة البرنامج، فمن المرجح أن ترى المشكلة المحتملة: هناك الكثير من الحيوانات في العالم، وكلها "تتحدث" بشكل مختلف: القطط مواء، البط الدجال، الثعابين هسهسة. هدفنا بسيط: تجنب إنشاء مجموعة من الأساليب للإدلاء بالتصويت. بدلاً من إنشاء طرق voiceCat()
للمواء والهسهسة voiceSnake()
وما إلى ذلك، نريد من voice()
الثعبان أن يهسهس، والقطة أن تموء، والكلب ينبح عندما يتم استدعاء الطريقة. يمكننا تحقيق ذلك بسهولة باستخدام آلية تجاوز الطريقة (التجاوز في Java) . تقدم ويكيبيديا التفسير التالي لمصطلح "التجاوز": تعد تجاوز الطريقة في البرمجة الشيئية إحدى ميزات لغة البرمجة التي تسمح لفئة فرعية أو فئة فرعية بتوفير تنفيذ محدد لطريقة تم تنفيذها بالفعل في إحدى الفئات الفائقة أو فئات الوالدين. وهو صحيح بشكل عام. يسمح لك التجاوز بأخذ طريقة للفئة الأصلية وكتابة تطبيقك الخاص لهذه الطريقة في كل فئة فرعية. سوف "يحل" التنفيذ الجديد محل الأصل في الفصل الفرعي. دعونا نرى كيف يبدو هذا مع مثال. لنقم بإنشاء 4 فئات لاحقة لفصلنا Animal
:
public class Bear extends Animal {
@Override
public void voice() {
System.out.println("Р-р-р!");
}
}
public class Cat extends Animal {
@Override
public void voice() {
System.out.println("Meow!");
}
}
public class Dog extends Animal {
@Override
public void voice() {
System.out.println("Woof!");
}
}
public class Snake extends Animal {
@Override
public void voice() {
System.out.println("Ш-ш-ш!");
}
}
اختراق حياتي صغير للمستقبل: لتجاوز أساليب الفئة الأصلية، انتقل إلى رمز الفئة التابعة في Intellij IDE a، اضغط على Ctrl+O وحدد " تجاوز الأساليب... " من القائمة. تعود على استخدام مفاتيح الاختصار منذ البداية، فهي ستسرع من كتابة البرامج! لتعيين السلوك الذي أردناه، قمنا ببعض الأشياء:
- لقد أنشأنا طريقة في كل فئة تابعة بنفس اسم الطريقة الموجودة في الفئة الأصلية.
-
أخبرنا المترجم أننا قمنا بتسمية الطريقة بنفس الطريقة الموجودة في الفئة الأصل لسبب ما: أردنا تجاوز سلوكها. بالنسبة لهذه "الرسالة" إلى المترجم، وضعنا تعليقًا توضيحيًا @Override على الطريقة .
التعليق التوضيحيOverride الموجود أعلى إحدى الطرق يخبر المترجم (والمبرمجين الذين يقرؤون الكود الخاص بك أيضًا): "كل شيء على ما يرام، هذا ليس خطأ أو نسيانًا. أتذكر أن مثل هذه الطريقة موجودة بالفعل، وأريد تجاوزها." - لقد كتبنا التنفيذ الذي نحتاجه لكل فئة فرعية. عند النداء، يجب أن تهسه الثعبان
voice()
، ويجب أن يهدر الدب، وما إلى ذلك.
public class Main {
public static void main(String[] args) {
Animal animal1 = new Dog();
Animal animal2 = new Cat();
Animal animal3 = new Bear();
Animal animal4 = new Snake();
animal1.voice();
animal2.voice();
animal3.voice();
animal4.voice();
}
}
إخراج وحدة التحكم: اللحمة! مواء! ررر! صه! عظيم، كل شيء يعمل كما ينبغي! لقد أنشأنا 4 متغيرات مرجعية للفئة الأصلية Animal
، وقمنا بتعيينها لأربعة كائنات مختلفة من الفئات التابعة. ونتيجة لذلك، يتصرف كل كائن بشكل مختلف. بالنسبة لكل فئة من الفئات التابعة، voice()
استبدلت الطريقة التي تم تجاوزها الطريقة "الأصيلة" voice()
من الفئة Animal
(والتي تقوم ببساطة بإخراج "الصوت!" إلى وحدة التحكم). التجاوز له عدد من القيود:
-
يجب أن تحتوي الطريقة التي تم تجاوزها على نفس وسيطات الطريقة الأصلية.
إذا قبلت إحدى الطرق
voice
في فئة أصل كإدخالString
، فيجب أن تقبل الطريقة التي تم تجاوزها في فئة فرعية أيضًا كإدخالString
، وإلا فسيقوم المترجم بإلقاء خطأ:public class Animal { public void voice(String s) { System.out.println("Voice! " + s); } } public class Cat extends Animal { @Override//error! public void voice() { System.out.println("Meow!"); } }
-
يجب أن يكون للطريقة التي تم تجاوزها نفس نوع الإرجاع مثل الطريقة الأصلية.
وإلا فإننا سوف نتلقى خطأ في الترجمة:
public class Animal { public void voice() { System.out.println("Voice!"); } } public class Cat extends Animal { @Override public String voice() { //error! System.out.println("Meow!"); return "Meow!"; } }
-
لا يمكن أيضًا أن يختلف مُعدِّل الوصول للطريقة المُتجاوزة عن الطريقة "الأصلية":
public class Animal { public void voice() { System.out.println("Voice!"); } } public class Cat extends Animal { @Override private void voice() { //error! System.out.println("Meow!"); } }
voice()
للجميع بدلا من مجموعة من الأساليب voiceDog()
، voiceCat()
وما إلى ذلك.
GO TO FULL VERSION