Java中的方法重寫呼叫
上學期學了java,一個暑假沒有用,很多java的“精髓”都忘記了。週末在寫資料結構的作業的時候,要求寫一個迴圈連結串列的類,並且繼承之前寫的一個線性表的類。因為重寫的一些重要的東西忘記了,花了大量的時間一直在報空指標異常,終於發現了問題,並請教了前輩才算是解決了這個問題。
呼叫重寫方法
首先,我建立了一個MyAbstractList的父類,裡面是一些實現線性表的方法。然後建立了一個CircularLinkedList的子類,繼承了MyAbstractList類中的方法。其中,父類裡面有兩個add()方法,如下:
public void add(E e) { this.add(int index,E e); System.out.println("Add parent o"); } public void add(int index,E e) { System.out.println("Add parent t"); }
接著,我在子類,也就是CircularLinkedList類裡面重寫了這兩個方法,如下:
@Override public void add(E element) { super.add(E e); System.out.println("Add child o"); } @Override public void add(int index,E element) { super.add(int index,E e); System.out.println("Add child t"); }
在測試類裡面建立了一個子類物件,並且呼叫了add(E element)方法,程式碼如下:
CircularLinkedList<Integer>list1 =new CircularLinkedList<Integer>();
list1.add(3);
}
我的腦海裡這段程式的輸出應該是這樣的:
Add child o
Add parent o
Add parent t
然而事實並非如此,真正的輸出是這樣的:
Add child o
Add parent o
Add child t
這是為什麼呢?原來,因為我new的物件是子類,也就是CircularLinkedList類,所以在父類中的 this.add(int index,E e)時,呼叫的並非是父類中的add(int index,E e),而是子類中的add(int index,E e)。這樣一來,問題就逐漸明瞭了。
Java中的多型
要滿足多型的條件,子類要重寫父類的方法。多型是父類引用指向子類物件。
值得注意的是,多型中,若子類中沒有重寫方法,則就運算元類中的方法名和父類中的方法名一樣(即子類僅僅過載了父類中的方法),那麼不能構成多型,而子類中的這個方法就和它自己建立的一個普通方法是一樣的,和父類並沒有關係。
另外,在使用多型時,呼叫子類方法的時候會先去看引用型別中是否有同樣的方法,即會先去看此方法是否被重寫,如果此方法不是被重寫的,也就是說,呼叫的子類中的方法是過載父類中的方法,父類中實際上是沒有這個方法的,那麼在呼叫這個方法的時候就會報錯。例子如下:
package test;
public class TestPolymorphic {
public static void main(String[] args) {
A test=new B();
test.printl();
}
}
class A{
void printl(int x) {
System.out.println("x is "+x);
}
}
class B extends A{
void printl() {
System.out.println("y is null");
}
}
編譯器會給出如下錯誤提示:
Exception in thread "main" java.lang.Error: Unresolved compilation problem: The method printl(int) in the type A is not applicable for the arguments ()
當代碼修改之後,如下:
public static void main(String[] args) {
A test=new B();
test.printl(10);
}
方法會呼叫A類中的printl()方法,並且輸出結果:x is 10
而當子類中重寫了父類中的方法之後,即程式碼如下:
package test;
public class TestPolymorphic {
public static void main(String[] args) {
A test=new B();
test.printl(10);
}
}
class A{
void printl(int x) {
System.out.println("x is "+x);
}
}
class B extends A{
void printl(int y) {
System.out.println("y is null");
}
}
呼叫的則是子類中的printl()方法,輸出結果為:y is null