عندما توفر فئة فرعية تطبيقًا محددًا لطريقة تم تعريفها بالفعل في فئتها الأصلية، يُطلق عليها اسم تجاوز الطريقة. يجب أن يكون للطريقة التي تم تجاوزها في الفئة الفرعية نفس معلمات الاسم ونوع الإرجاع مثل الطريقة في الفئة الأصلية.
قواعد لتجاوز الطريقة
- يجب أن تتطابق معلمات الاسم ونوع الإرجاع مع الطريقة الأصلية.
- تختار Java الطريقة التي سيتم تشغيلها في وقت التشغيل استنادًا إلى نوع الكائن الفعلي وليس فقط نوع المتغير المرجعي.
- لا يمكن تجاوز الأساليب الثابتة.
- ال @تجاوز التعليق التوضيحي يلتقط أخطاء مثل الأخطاء المطبعية في أسماء الطرق.
class Animal { void move(){ System.out.println( 'Animal is moving.'); } void eat(){ System.out.println( 'Animal is eating.'); } } class Dog extends Animal{ @Override void move(){ // move method from Base class is overriden in this // method System.out.println('Dog is running.'); } void bark(){ System.out.println('Dog is barking.'); } } public class Geeks { public static void main(String[] args) { Dog d = new Dog(); d.move(); d.eat(); d.bark(); } }
الإخراج
Dog is running. Animal is eating. Dog is barking.
توضيح: تحدد فئة الحيوان الوظائف الأساسية مثل يتحرك() و يأكل() . فئة الكلاب ترث من الحيوان و يتجاوز طريقة move() لتوفير سلوك معين الكلب يركض. يمكن لكلا الفئتين الوصول إلى أساليبهما الخاصة. عند إنشاء كائن كلب، يتم تنفيذ استدعاء move() الطريقة التي تم تجاوزها.

حالات خاصة في التجاوز
1. استدعاء الأسلوب الأصلي باستخدام super
ال الكلمة الرئيسية الفائقة يمكن استدعاء طريقة الفئة الأصل من طريقة التجاوز.
Javaclass Parent{ void show(){ System.out.println('Parent's show()'); } } class Child extends Parent{ @Override void show(){ super.show(); System.out.println('Child's show()'); } } public class Main{ public static void main(String[] args){ Parent obj = new Child(); obj.show(); } }
الإخراج
Parent's show() Child's show()
2. لا يمكن تجاوز الطرق النهائية
إذا كنا لا نريد تجاوز الطريقة، فإننا نعلن أنها كذلك أخير . يرجى الاطلاع استخدام النهائي مع الميراث .
ص في البرمجة جJava
class Parent{ // Can't be overridden final void show(){ } } class Child extends Parent{ // This would produce error void show() {} }
الإخراج :
3. الطرق الثابتة
- لا يمكن تجاوز الأساليب الثابتة؛ يؤدي تحديد طريقة ثابتة في فئة فرعية بنفس التوقيع الموجود في الفئة الفائقة إلى إخفاء طريقة الفئة الفائقة.
- يمكن تجاوز طرق المثيل ولكن لا يمكن للفئة الفرعية تجاوز الطريقة الثابتة للفئة الفائقة.
- الطريقة الثابتة في فئة فرعية بنفس التوقيع مثل الطريقة الثابتة للفئة الفائقة تخفي الطريقة الأصلية.
class Parent{ static void staticMethod(){ System.out.println('Parent static method'); } void instanceMethod(){ System.out.println('Parent instance method'); } } class Child extends Parent{ static void staticMethod(){ // Hides Parent's static method System.out.println('Child static method'); } @Override void instanceMethod(){ // Overrides Parent's instance method System.out.println('Child instance method'); } } public class GFG{ public static void main(String[] args){ Parent p = new Child(); // Calls Parent's static method (hiding) p.staticMethod(); // Calls Child's overridden instance method p.instanceMethod(); } }
الإخراج
Parent static method Child instance method
4. الطرق الخاصة
- لا يمكن تجاوز الأساليب الخاصة لأنها غير مرئية للفئات الفرعية.
- يتم التعامل مع أسلوب الفئة الفرعية الذي يحمل نفس الاسم كأسلوب مستقل جديد لا علاقة له بالفئة الأصلية.
class Parent{ private void display(){ System.out.println('Parent private method'); } } class Child extends Parent{ void display(){ // This is a new method not overriding System.out.println('Child method'); } } public class GFG{ public static void main(String[] args){ Child c = new Child(); // Calls Child's method c.display(); } }
الإخراج
Child method
5. أنواع الإرجاع المتغيرة
- في طريقة التجاوز، يمكن أن يكون نوع الإرجاع لطريقة التجاوز فئة فرعية من نوع الإرجاع للطريقة المتجاوزة.
- تُعرف هذه الميزة بنوع الإرجاع المتغير وتسمح بأنواع إرجاع أكثر تحديدًا في الفئة الفرعية.
class Parent{ Parent getObject(){ System.out.println('Parent object'); return new Parent(); } } class Child extends Parent{ @Override // Covariant return type Child getObject() { System.out.println('Child object'); return new Child(); } } public class GFG{ public static void main(String[] args){ Parent obj = new Child(); // Calls Child's method obj.getObject(); } }
الإخراج
Child object
معالجة الاستثناءات في التجاوز
- لا يمكن لطريقة التجاوز طرح استثناءات جديدة أو أوسع نطاقًا من الطريقة الموجودة في الفئة الفائقة.
- يمكنه طرح استثناءات محددة أقل أو أضيق.
- يمكنه طرح أي استثناءات لم يتم التحقق منها (مثل RuntimeException) بغض النظر عن طريقة الطبقة الفائقة.
import java.io.IOException; class Parent { void display() throws IOException { System.out.println('Parent method'); } } class Child extends Parent { @Override void display() throws IOException { System.out.println('Child method'); } } public class GFG{ public static void main(String[] args){ // Parent reference Child object Parent obj = new Child(); try{ // Calls Child's overridden method obj.display(); } catch (IOException e){ System.out.println('Exception caught: ' + e.getMessage()); } } }
الإخراج
Child method
لماذا نستخدم طريقة التجاوز؟
- لتغيير أو تحسين سلوك أسلوب موجود في فئة فرعية.
- لتحقيق تعدد الأشكال في وقت التشغيل — تعتمد استدعاءات الأسلوب على نوع الكائن الفعلي.
- لإعادة استخدام أسماء الأساليب بشكل منطقي، يتم تقليل التكرار.
مثال واقعي: نظام إدارة الموظفين
دعونا نفهم التجاوز بقياس حقيقي.
تخيل نظام إدارة الموظفين في المنظمة. يتشارك جميع الموظفين في بعض السلوكيات مثل riseSalary() وprogrammer() ولكن المنطق يختلف باختلاف الأدوار مثل المدير أو المهندس. يمكننا إنشاء مصفوفة موظفين واحدة حيث يكون الموظفون الفرديون من أنواع مختلفة (تقنية المبيعات وما إلى ذلك) واستدعاء وظائفهم. هذا يبسط الكود العام كثيرًا.
Javaabstract class Employee { abstract void raiseSalary(); abstract void promote(); } class Manager extends Employee{ @Override void raiseSalary(){ System.out.println( 'Manager salary raised with incentives.'); } @Override void promote(){ System.out.println( 'Manager promoted to Senior Manager.'); } } class Engineer extends Employee{ @Override void raiseSalary(){ System.out.println( 'Engineer salary raised with bonus.'); } @Override void promote(){ System.out.println( 'Engineer promoted to Senior Engineer.'); } } public class Company{ public static void main(String[] args){ Employee[] employees = { new Manager() new Engineer() }; System.out.println('--- Raising Salaries ---'); for (Employee e : employees){ e.raiseSalary(); } System.out.println('n--- Promotions ---'); for (Employee e : employees) { e.promote(); } } }
الإخراج
--- Raising Salaries --- Manager salary raised with incentives. Engineer salary raised with bonus. --- Promotions --- Manager promoted to Senior Manager. Engineer promoted to Senior Engineer.
توضيح: على الرغم من الإشارة إلى كل من كائنات المدير والمهندس باستخدام نوع الموظف، تستدعي Java الأساليب التي تم تجاوزها للكائنات الفعلية في وقت التشغيل مما يوضح إرسال الأسلوب الديناميكي (تعدد الأشكال في وقت التشغيل).
ميغابايت إلى غيغابايت
مقالة ذات صلة: طريقة التحميل الزائد وتجاوز الطريقة