構造器訪問權限
public:所有的類都可以使用;
protected: 本包以及子類可以使用;
default:本包可以使用;
private:僅本類可以使用。
一.默認構造器:
構建過程是從基類向外擴散的,所以基類在導出類可以訪問它之前,就已經完成了初始化
package ch7_05; class A{ public A(){ System.out.println("I am A"); } } class B{ public B(){ System.out.println("I am B"); } } public class C extends A{ B b = new B(); public static void main(String[] args) { new C(); } }/* output:
I am A
I am B
*///~
二.帶參數構造器
默認構造器編譯器可以輕松調用它是因為不必考慮要傳遞什么樣的參數的問題,但是如果沒有默認的基類構造器,或者想調用一個帶參數的基類構造器,就必須用關鍵字super顯式地編寫調用基類構造器的語句,並且配之以適當的參數
package object; import static net.mindview.util.Print.*; class Game{ Game(int i) { print("Game constructor"); } } class BoardGame extends Game{ BoardGame(int i) { super(i); //必須在構造器的第一行 super must consructor's first row print("BoardGame constructor"); } } public class Chess extends BoardGame{ Chess() { super(1); //如果基類有默認構造器,導出類一定要用super()在第一行顯示的調用基類的帶參構造器 print("Chess constructor"); } public static void main(String[] args) { Chess x = new Chess(); } }/* output: Game constructor BoardGame constructor Chess constructor *///~
三.構造器的調用順序,基類的構造器總是在導出類的構造過程中被調用,而且按照繼承層次逐漸向上鏈接,以使每個基類的構造器都能得到調用,(第九章多態)
1.調用基類構造器,這個步驟會不斷重復執行下去,首先是構造這種層次結構的根,然后是下一層導出類,等等,直到最底層的導出類(在任何其它事務發生之前,將分配給對象的存儲空間初始化為二進制的零
2.按聲明順序調用成員的初始化方法
3.調用導出類構造器的主體
package object; //: polymorphsim/Sandwich.java // Order of constructor call import static net.mindview.util.Print.*; class Meal{ Meal(){print("meal");} } class Bread{ Bread(){print("bread");} } class Cheese{ Cheese(){print("CZheese");} } class Lettuce extends Meal{ Lettuce(){print("Lettuce");} } class Lunch extends Meal{ Lunch(){print("Lunch");} } class PortableLunch extends Lunch{ PortableLunch(){print("PortableLunch");} } public class Sandwich extends PortableLunch{ private Bread b = new Bread(); private Cheese c = new Cheese(); private Lettuce l =new Lettuce(); public Sandwich(){print("sandwich");} public static void main(String[] args) { new Sandwich(); } }/* output: meal Lunch PortableLunch bread CZheese meal Lettuce sandwich *///:~
四.構造器內部的多態行為
1.如果在構造器內部調用了正在構造的對象的某個動態綁定方法,那么該動態方法就會在正在構造對象還未初始化之前就會被調用,這肯定會招致災難,所以在構造器內唯一能夠安全調用的那些方法是基類的final方法(也適用於private,它們自動屬於final方法),這些方法不能被覆蓋,也就不會出現問題.
//polymorphism/Polyconstructors.java //constructors and poly morphism //don't produce what you mght expect package object; class Glyph{ void draw() { System.out.println("ZGlyph.draw()"); } Glyph() { System.out.println("Glyph() before draw()"); draw(); //在導出類RoundGlyph還未初始化之前就調用了RoudnGlyph.draw()方法 System.out.println("Glyph() after draw()"); } } class RoundGlyph extends Glyph{ private int radius = 1; RoundGlyph(int r) { radius = r; System.out.println("roundglyph..roundglyph(), radius = " + radius); } void draw() //綁定的動態方法 { System.out.println("Roundglyph.draw(), radius = " + radius); } } public class Polyconstructors{ public static void main(String[] args) { new RoundGlyph(5); } }/* output: Glyph() before draw() Roundglyph.draw(), radius = 0 //在導出類RoundGlyph還未初始化之前就調用了RoudnGlyph.draw()方法,radius不是1 Glyph() after draw() roundglyph..roundglyph(), radius = 5 *///:~
