構造器內部的多態方法的行爲

public class PolyContructors {

	public static void main(String[] args) {
		new RoundGlyph(5);
	}
}

class Glyph {
	void draw() {
		System.out.println("Glyph.draw()");
	}
	
	public Glyph() {
		System.out.println("Glyph's Constructor");
		System.out.println("before draw...");
		draw();
		System.out.println("after draw...");
	}
}

class RoundGlyph extends Glyph {
	private int  radius = 1;
	void draw() {
		System.out.println("RoundGlyph.draw() -> radius=" + radius);
	}
	
	public RoundGlyph(int r) {
		radius = r;
		System.out.println("RoundGlyph's Constructor");
	}
}

輸出:java

Glyph's Constructor
before draw...
RoundGlyph.draw() -> radius=0
after draw...
RoundGlyph's Constructor

輸出結果radius爲何是0而不是1?
think in java說Glyph的構造器調用draw()方法時,radius不是默認初始值1,而是0(?),我理解的是radius要麼是發現變量未定義,要麼找到變量的定義並初始化爲1,爲何是0呢.....對象.在堆裏已分配了空間,初始化成了默認值0?安全

初始化的實際過程:函數

  1. 在其餘任何事物發生以前,將分配給對象的存儲空間初始化成二進制的零。
  2. 如前所述那樣調用基類構造器,此時,調用被覆蓋後的draw()方法(注意,要在調用RoundGlyph構造器以前調用),因爲步驟1 的緣故,咱們此時會發現radius的值爲0
  3. 按照聲明的順序調用成員的初始化方法
  4. 調用導出類的構造器主體

在構造器內惟一可以安全調用的那些方法是基類中的final方法(也適用private方法,它們自動屬於final方法),這些方法不能被覆蓋,故不存在這個問題。code

另,若是父類構造器調用了被子類重寫的方法,且經過子類構造函數建立子類對象,調用了這個父類構造器(不管顯示仍是隱式),就會致使父類在構造時實際上調用的是子類覆蓋的方法。對象

相關文章
相關標籤/搜索