المنهج المهيمن في جافا
يتحقق المنهج المهيمن "Method Overriding" عندما تقوم فئة فرعية بإلغى المناهج الغير ثابت المعرفة في الفئة الفائقة، وبعد ذلك تنفيذ المنهج الجديد في الفئة الفرعية التي يُتِم تنفيذها.
تعريف المنهج الجديد يجب ان يكون له نفس توقيع الفئة (أي اسم المنهج والمعلمات "parameters") ، ونوع الإرجاع "return type". ويتم اختيار المعلمات "parameters" و نوع الإرجاع "return type" فقط كمعايير لمطابقة توقيع الفئة. فإذا كان للفئة الفرعية معلمات المنهج على النحو النهائي "final" فهو لا يهم بالنسبة لسيناريوهات المنهج المهيمن فيبق صحيحا. التعريف الجديدة للمنهج لا يضييق على إمكانية الوصول للمنهج، ولكن من الممكن توسيعها. التعريف الجديد للمنهج فقط تحديد جميع أو لا شيء ، أومجموعة فرعية من الفئات الستثنات (بما في ذلك الفئات الفرعية الخاصة بهم) المحدد في فقرة "throws" للفئة المهيمنة الموجودة في فئة الفائقة
برنامج لشرح المفاهيم المختلفة للمنهج المهيمن في جافا
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126class CustomException extends Exception{
}
class SuperClassWithDifferentMethods{
protected int field1 = 10;
protected static int field2 = 20;
public void method1() {
System.out.println("SuperClassWithDifferentMethods .method1()");
}
public final void method2(){
System.out.println("SuperClassWithDifferentMethods .method2()");
}
private void method3() {
System.out.println("SuperClassWithDifferentMethods .method3()");
}
private final void method4(){
System.out.println("SuperClassWithDifferentMethods .method4()");
}
public static void method5() {
System.out.println("SuperClassWithDifferentMethods .method5()");
}
public void method6() throws Exception {
System.out.println("SuperClassWithDifferentMethods .method6()");
}
private void method7(){
System.out.println("SuperClassWithDifferentMethods .method7()");
}
private void method8(int x){
System.out.println("SuperClassWithDifferentMethods .method8()");
}
public static void method9() {
System.out.println("SuperClassWithDifferentMethods .method9()");
}
}
class OverridingClass extends SuperClassWithDifferentMethods {
public int field1 = 30;
public static int field2 = 40;
public void method1() {
System.out.println("OverridingClass.method1()");
}
//We can't override a public final method
//public final void method2(){
//System.out.println("OverridingClass.method2()");
//}
private void method3(){
System.out.println("OverridingClass.method3()");
}
private final void method4(){
System.out.println("OverridingClass.method4()");
}
public static void method5() {
System.out.println("OverridingClass.method5()");
}
public void method6() throws CustomException{
System.out.println("OverridingClass.method6()");
}
public void method7(){
System.out.println("OverridingClass.method7()");
}
public void method8(final int x){
System.out.println("OverridingClass.method8()");
}
//A static method cannot be overridden to be non-static instance method
/*public void method9() {
System.out.println("OverridingClass.method9()");
}*/
}
public class MethodOverridingDemo {
public static void main(String[] args) {
OverridingClass oc1 = new OverridingClass();
SuperClassWithDifferentMethods sc3 = new OverridingClass();
oc1.method1();
oc1.method2();
// Since its private, the below 2 methods are not visible
/* oc1.method3();
oc1.method4();*/
oc1.method5();
try {
oc1.method6();
} catch (CustomException e) {
e.printStackTrace();
}
oc1.method7();
oc1.method8(100);
System.out.println("oc1.field1 : "+oc1.field1);
System.out.println("oc1.field2 : "+oc1.field2);
System.out.println("sc3.field1 : "+sc3.field1);
System.out.println("sc3.field2 : "+sc3.field2);
sc3.method5();
OverridingClass overClass = new OverridingClass();
SuperClassWithDifferentMethods supClass = (SuperClassWithDifferentMethods)overClass;
supClass.method5();
supClass.method1();
}
}
Output
OverridingClass.method1()
SuperClassWithDifferentMethods.method2()
OverridingClass.method5()
OverridingClass.method6()
OverridingClass.method7()
OverridingClass.method8()
oc1.field1 : 30
oc1.field2 : 40sc3.field1 : 10
sc3.field2 : 20
SuperClassWithDifferentMethods.method5()
SuperClassWithDifferentMethods.method5()
OverridingClass.method1()
تعريفات المنهج الجديد OverridingClass في الفئة الفرعية لها نفس التوقيع و نوع الإرجاع "return type" متل الفئة الفائقة SuperClassWithDifferentMethods . المنهج المهيمن الجديد method6 يحدد مجموعة من الاستثناءات (CustomException). تعريف المنهج المهيمن الجديد method7 يوسع إمكانية وصول الخاص "private" إلى العام "public". و المنهج المهيمن method8 يعلن المعلمة "parameter" على اساس نهائية "final"، وهي ليست جزءا من توقيع المنهج و هذا المنهج المهيمن يعمل جيدا. المنهج الثابت "static method" لا يمكن تجاوزه ليكون مثيل لمنهج غير ثابتة كما هو موضح في الإعلان عن المنهج المهيمن للمنهج method9. المنهج الثابتة "static method" هو فئة محددة وليس جزءا من أي كائن، في حين يتم استدعاء المناهج المهيمن بالنيابة عن الكائنات من الفئة الفرعية. لا توجد مثل هذه القيود على الحقول، وبالنسبة للحقول فقط أسماء الحقول هي المطلوبة. و لا يمكن تجاوز المنهج النهائي "final method" ، ومحاولة هذا الأمر سيؤدي إلى خطأ في وقت التحويل البرمجي. فالمنهج الخاص "private method" لا يمكن الوصول إليه من خارج الفئة التي تم تعريفه فيها ، وبالتالي ، لا يمكن للفئة الفرعية تجاوزه.
يجب على الفئة الفرعية استخدام الكلمة الأساسية "super" من أجل استدعاء المنهج الذي تم تجاوزه "overridden method" من الفئة المتفوقة. و لا يمكن لفئة فرعية تجاوز حقول الفئة الفائقة، ولكن يمكنها إخفائهم. يمكن للتعليمات البرمجية في فئة فرعية استخدام الكلمة الأساسية "super" للوصول إلى الأعضاء "members" ، بما في ذلك الحقول المخفية.
ويجب ملاحظة الفرق بين استدعاء المناهج المثيلة "instance methods" في الكائن والوصول إلى حقول كائن. عندما يتم استدعاء منهج مثيل لكائن باستخدام مرجع ، فهي فئة الكائن الحالي و يشار اليها بالمرجع "reference" ، وليس نوع المرجع هو الذي يحدد تطبيقات المنهج التي سيتم تنفيذها. عندما يكون حقل كائن قد تم الوصول إلىه باستخدام مرجع، فهو نوع المرجع، وليس فئة الكائن الحالي المرموز له بالمرجع، و يحدد هذا أيّ حقل سيكون قابل للوصول. ويتجلى هذا في البرنامج أعلاه