1. 程式人生 > >Java中的方法重寫呼叫

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