Java之調用被子類重載的方法

版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/Julin1214/article/details/51505008

    有一種特殊的重寫方法,就是當子類重寫父類方法,父類表面上只是調用屬於自己的、被子類重寫的方法,但隨着contex的執行改變,將會變成父類直接調用子類的方法。


public class Animal {
	private String desc;
	public Animal() {
		System.out.println("Animalgouzao"+desc);
		// TODO Auto-generated constructor stub
		this.desc=getDesc();
		System.out.println("Animalgouzao!!!!!"+desc);
		
	}
	public String getDesc(){
		System.out.println("Animal getDesc");
		return "Anmial";
	}
	public String toString(){
		System.out.println("Animal toString");
		return desc;
	}

}

public class Dog extends Animal{
	private String name;
	private double weight;
	public Dog(String name,double weight) {
		// TODO Auto-generated constructor stub
		System.out.println("Doggouzao::::"+name+weight);
		this.name=name;
		this.weight=weight;
		System.out.println("Doggouzao"+name+weight);
	}
	/* (non-Javadoc)
	 * @see Animal#getDesc()
	 */
	@Override
	public String getDesc() {
		// TODO Auto-generated method stub
		System.out.println("DogGetDesc::::"+name+weight);
		return "Dog[name="+name+",weight="+weight+"]";
	}
	

}
public static void main(String[] args) {
		System.out.println(new Dog("xiaohua", 20.5));
}
運行結果如下:
Animalgouzaonull
DogGetDesc::::null0.0
Animalgouzao!!!!!Dog[name=null,weight=0.0]
Doggouzao::::xiaohua20.5
Doggouzaoxiaohua20.5
Animal toString
Dog[name=null,weight=0.0]
根據輸出的結果,我們來進行一步步的解析:
程序在執行Dog的時候,會隱式調用父類的無參構造,無參構造裏調用的getDesc方法其實不是父類的方法而是Dog子類的方法。此時程序還沒有執行子類的構造器方法,所以Dog的實例變量值都保持了默認值。因此Dog的getDesc()方法的返回值就是默認值了。也就是我們看到的結果。然後再去執行Dog的構造方法,程序Dog對象的兩個實例變量賦值,只是它的desc的實例變量值爲默認值。該程序產生這種輸出的原因在於在執行調用父類無參構造的時候調用的getDesc()方法是被子類重寫過的方法。這樣使得Dog實例變量賦值在getDesc()方法之後執行,因此不能得到它的實例變量值。
要想改變這種情況的話,就避免在父類中調用被子類重寫過的方法。這樣就保證了對Dog對象的實例變量賦值的語句,在getDesc()方法之前被執行,從而使得getDesc()方法得到實例變量值。


注意:如果父類構造器調用了被子類重寫的方法,且通過子類構造器來創建子類對象,調用了父類構造器,就會導致子類的重寫方法在子類構造器的所有代碼之前執行,從而導致之類重寫方法訪問不到子類的實例變量值的情形。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章