English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
في هذا الدرس، سنستخدم الأمثلة لدراسة تغطية الطرق في Java.
في الدرس السابق، تعرفنا على الوراثة. الوراثة هي خاصية في OOP تسمح لنا بإنشاء كائن جديد (كائن فرعي) من كائن موجود (كائن أب) وسيحصل الكائن الفرعي على خصائص وطرق الكائن الأب.
إذا تم تعريف نفس الطريقة في الكائن الأب والكائن الفرعي، فإن الطريقة في الكائن الفرعي ستغطي الطريقة في الكائن الأب. هذا يسمى تغطية الطريقة (أو إعادة كتابة الطريقة).
class Animal { public void displayInfo() { System.out.println("أنا حيوان."); } } class Dog extends Animal { @Override public void displayInfo() { System.out.println("أنا كلب."); } } class Main {}} public static void main(String[] args) { Dog d1 = new Dog(); d1.displayInfo(); } }
الإخراج:
أنا كلب.
في البرنامج المذكور أعلاه، الطريقة displayInfo() موجودة في كلا الكائن الأب Animal والكائن الفرعي Dog.
عند استدعاء دالة displayInfo() باستخدام كائن d1 (كائن فرعي)، سيتم استدعاء الطريقة في الكائن الفرعي Dog. الطريقة displayInfo() في الكائن الفرعي تغطي الطريقة نفسها في الكائن الأب.
الاحتياط في مثالنا استخدمنا تعليق @Override. في Java، التعليقات هي المعلومات التي نقدمها إلى معالج البرمجة (compiler) كبيانات إضافية. هنا، تعليق @Override يخبر معالج البرمجة أن الطريقة التي تليها ستغطي الطريقة في الكائن الأب (superclass).
ليس إلزاميًا استخدام @Override. ولكن يجب أن يتبع هذا الطريقة جميع القواعد التي يجب اتباعها عند الإعادة الكتابة. وإلا سيقوم المُعالج بإنشاء خطأ.
يجب أن يكون لدي الأب والفرعية نفس الاسم للطريقة، نفس النوع من الإرجاع والقائمة على المدخلات.
لا يمكننا إعادة كتابة الطريقة المعلنة كـ final و static.
يجب أن نعيد كتابة الطريقة التجريبية في الأب دائمًا (سيتم مناقشتها في دروس لاحقة).
من المشاكل الشائعة التي تحدث عند تنفيذ إعادة الكتابة في Java هي:
هل يمكننا الوصول إلى طريقة الأب بعد إعادة الكتابة؟
الإجابة هينعم. لنتمكن من الوصول إلى طريقة الأب من الفرعية، نستخدم كلمة المفتاح super.
class Animal { public void displayInfo() { System.out.println("أنا حيوان."); } } class Dog extends Animal { public void displayInfo() { super.displayInfo(); System.out.println("أنا كلب."); } } class Main {}} public static void main(String[] args) { Dog d1 = new Dog(); d1.displayInfo(); } }
الإخراج:
أنا حيوان. أنا كلب.
في هذا المثال، قام الفرعية Dog بإعادة الكتابة على طريقة displayInfo() في الأب Animal.
عندما نستخدم كائن d1 من الفرعية Dog لاستدعاء طريقة displayInfo()، سيتم استدعاء الطريقة في الفرعية Dog. لن يتم استدعاء الطريقة في الفرعية الأب.
في داخل طريقة displayInfo() في الفرعية Dog، نستخدم super.displayInfo() لاستدعاء طريقة displayInfo() في الأب.
على الرغم من ذلك، ليست بناء الحالة في Java معقولة لأنها لا تُورث. لذلك، لا يوجد مشكلة في إعادة كتابة بناء الحالة في Java.
لكن يمكننا استدعاء بناء الحالة الأب من الفرعية. لفهم المزيد، يرجى زيارةكلمة المفتاح Java super.
يمكن أن يكون لدي الطريقة نفس الاسم المعلن في الأب والفرعية، لكن هناك قيود.
يمكننا فقط استخدام وحدات الوصول التي يمكن استخدامها في الفرعية التي تقدم وصولًا أكبر من وحدات الوصول في الأب. على سبيل المثال،
افترض أن يتم تعريف الطريقة myClass() في الكائن الأب كـ protected. ثم، يمكن أن يكون الطريقة المماثلة في الفرعية العامة أو protected، لكن لا يمكن أن تكون private.
class Animal { protected void displayInfo() { System.out.println("أنا حيوان."); } } class Dog extends Animal { public void displayInfo() { System.out.println("أنا كلب."); } } class Main {}} public static void main(String[] args) { Dog d1 = new Dog(); d1.displayInfo(); } }
الإخراج:
أنا كلب.
في المثال السابق، قامت الطبقة الفرعية Dog بتعديل طريقة displayInfo() في الطبقة الأب Animal.
كلما استخدمنا d1 (عنصر فرعي) لنطق displayInfo()، يتم استدعاء الطريقة في الطبقة الفرعية.
لاحظ أن displayInfo() تم إعلانها كمعروفة في كلاس الأب Animal. هذه الطريقة في كلاس Dog تملك معرفات الوصول العامة (public). هذا مسموح به لأن العامة تقدم صلاحيات الوصول الأكبر من المعروفة.
في Java، يتم إنشاء كلاسات الأب (الأساسية) كأباء للفئات الأخرى. ويفترض، إذا كانت الفئة تحتوي على طريقة抽象ة، أن يتم تعديلها.
في الدروس اللاحقة، سنتعلم المزيد عن تعديل كلاسات الأب وطرق الأب.