1. 對象的創建由什么完成
- 實際通過調用該類的有參或無參構造方法創建對象,但對象的創建并不由構造器完成.實際上通過new關鍵字調用構造方法時,系統在執行構造方法前會為該對象分配內存空間,并為這個對象執行默認初始化,此時該對象已經創建完成,然后通過構造器將該對象返回.
- 構造器無需指定返回類型,但并不是沒有返回類型,實際返回的當前對象類型,如果沒有返回類型則完全可以使用void返回關鍵字.
2. 構造方法什么時候會調用
public class Person{
private String name;
private int age;
public Person(String name){
this(name,0);/**!!!**/
System.out.println(name);
}
public Person(String name,int age){
System.out.println(name+""+age);
}
}
- 創建對象時
Person person = new Person("nan");
- 在構造方法中調用另外一個構造方法
如上 this(name,0);
該調用必須位于構造方法內,并且必須位于首行且只能調用一次。 如果沒有指定的話構造方法默認首行為super(),去調用父類的無參構造方法,如果指定了this(),或者super,則系統不會添加。
3. 子類與父類
子類中擁有父類的變量和方法,包括靜態成員和靜態方法
- 靜態成員變量和父類中的相同時:子類覆蓋父類,則相當于各自分別有個變量
- 成員變量和父類中的相同時:子類覆蓋父類,如果要在子類中訪問父類中的該變量時則需使用super關鍵字
- 成員方法和父類中成員方法名和參數列表相同時:此時為重寫,如果要在子類中訪問父類的該方法時可使用super關鍵字
- 子類構造器中調用父類的構造器時使用super(...)調用,而且必須放首行,且只能調用一次.
注意
子類不能繼承和重寫父類的構造方法,而是采用隱式調用父類的構造方法 ,即如果子類沒有顯示調用父類的構造方法,系統會自動加入super()方法,該方法會去調用父類的無參構造方法,如果父類沒有指定無參構造方法(系統自動添加,手動添加均可),則編譯錯誤.如果顯示調用父類構造方法,則系統不會隱式調用。
4. 子類繼承父類引起的問題
破壞了父類的封裝性,造成子類和父類的嚴重耦合. //子類可以直接訪問父類的成員以及方法并重寫
為了避免這些問題在設計父類時應盡量遵從以下原則:
- 父類成員盡可能使用private修飾
- 不要讓子類隨意重寫父類的方法 父類中的方法用final修飾時子類則無法重寫父類方法.
- 盡可能不在父類中調用可能被子類重寫的方法. // 因為子類重寫的方法有可能調用了自己類的一些成員,系統在初始化對象時先初始化父類,從而導致空指針異常
class Base{
public Base(){
test();
}
public void test(){
System.out.println("父類中的test方法");
}
}
class Sub extends Base{
private String name;
public void test(){
System.out.println("Sub name length:"+name.length());
}
public static void main(String[]args){
Sub sub = new Sub();//會引起空指針異常,首先會執行父類的無參構造方法,并調用test()方法,由于實際對象為Sub,則根據多態會調用子類重寫的test方法,又因為子類name變量還沒有被初始化,從而引起空指針異常.
}
}