關於建立子類物件呼叫父類構造,父類構造中的this
先說結論,建立子類物件的時候不會建立父類物件,只是會呼叫父類的構造來初始化子類物件的屬性。此時如果在父類的構造中引用this,這個this其實是子類物件而且是一個未初始化的對想。
上程式碼:首先證明父類構造中的this是子類物件,這個很簡單
//父類 public class Parent { public Parent() { System.out.println("父類構造中的this="+this); } } //子類 public class Sub extends Parent { public Sub() { System.out.println("子類構造中的this"+this); } public static void main(String[] args) { new Sub(); new Sub(); new Sub(); } }
//列印結果
父類構造中的this=top.liuzhihong.polymorphic.a.Sub@1b6d3586
子類構造中的thistop.liuzhihong.polymorphic.a.Sub@1b6d3586
父類構造中的this=top.liuzhihong.polymorphic.a.Sub@4554617c
子類構造中的thistop.liuzhihong.polymorphic.a.Sub@4554617c
父類構造中的this=top.liuzhihong.polymorphic.a.Sub@74a14482
子類構造中的thistop.liuzhihong.polymorphic.a.Sub@74a14482
再來證明這個this是一個未初始化的物件,其實很好理解,呼叫父類構造的目的就是初始化子類物件的屬性,所以肯定先有一個空的子類物件然後去父類中初始化它的屬性,然後再到子類中初始化屬性並呼叫子類構造完成最後的初始化。
只需重寫toString即可證明
//父類 public class Demo { public Demo() { System.out.println("父類構造"); System.out.println("creating:" + this); } } //子類 public class DemoTest extends Demo{private static int counter = 0; private final int id = counter++; public DemoTest() { System.out.println(this.id); System.out.println(this); } @Override public String toString() { System.out.println(id); return "DemoTest id=" + id; } public static void main(String[] args) { new DemoTest(); System.out.println("---"); new DemoTest(); System.out.println("----"); new DemoTest(); } }
//執行結果,我們發現傳入父類的物件屬性id始終為0,如果不是上面的結論證明了這個this就是子類物件這裡可能會誤解。
父類構造
0
creating:DemoTest id=0
0
0
DemoTest id=0
---
父類構造
0
creating:DemoTest id=0
1
1
DemoTest id=1
----
父類構造
0
creating:DemoTest id=0
2
2
DemoTest id=2
總結:構造器可以理解成為一個 static方法,而構造器不是用來建立物件的而是在建立物件後進行初始化屬性的。而new是用來建立物件的,建立物件的過程中會呼叫這個構造器。