1. 程式人生 > >【學習筆記】 唐大仕—Java程式設計 第5講 深入理解Java語言之5.3 物件構造與初始化

【學習筆記】 唐大仕—Java程式設計 第5講 深入理解Java語言之5.3 物件構造與初始化

物件構造與初始化

構造方法
  • 構造方法(constructor)

    • 物件都有構造方法
    • 如果沒有,編譯器加一個default構造方法
  • 抽象類(abstract)有沒有構造方法?

    • 答案:抽象類也有構造方法。實際上,任何類都有自己的構造方法
呼叫本類或父類的構造方法
  • 呼叫本類或父類的構造方法

    • this呼叫本類的其他構造方法
    • super呼叫父類的構造方法
    • this和super要放在第一條語句,且只能夠有一條
  • 如果沒有this及super,則編譯器自動加上super()

    ,即呼叫直接父類不帶引數的構造方法

  • 因為必須令所有父類的構造方法都得到呼叫,否則整個物件的構建就可能不正確

建立物件時初始化
  • p = new Person(){{ age = 18; name = "李明" }}
  • 這樣可以針對沒有相應建構函式,但又要賦值的情況
  • 注意雙括號
例項初始化與靜態初始化
  • 例項初始化(Instance Initializers)

  • 在類中直接寫

    • { 語句.... }
    • 例項初始化,先於構造方法{}中的語句執行
  • 靜態初始化(Static Initializers)

    • static{ 語句.... }
    • 靜態初始化,在第一次使用這個類時要執行
    • 但其執行的具體時機是不確定的
      • 但是可以肯定的是:總是先於例項的初始化
構造方法的執行過程
  • 構造方法的執行過程遵照以下步驟:

    • 呼叫本類或父類的構造方法,直至最高一層(Object)
    • 按照宣告順序執行欄位的初始化賦值
    • 執行建構函式中的各語句
  • 簡單的說:

    • 先父類構造,再本類成員賦值,最後執行構造方法中的語句
一個問題
  • 構造方法內部呼叫別的方法
  • 如果這個方法是虛方法(不是用private,private,final修飾的方法),結果如何?
    • 從語法上來說這是合法的,但有時會造成事實上的不合理
class ConstructInvokeMetamorph 
{
    public static void main(String[] args){ 
        Person p = new Student("李明", 18, "北大");
    }
}

class Person
{
    String name="未命名"; 
    int age=-1;
    Person( String name, int age ){
        this.name=name; this.age=age; 
        sayHello();
    }
    void sayHello(){
        System.out.println( "我是一個人,我名叫:" + name + ",年齡為:"+ age );
    }
}

class Student extends Person
{
    String school="未定學校";
    Student( String name, int age, String school ){
        super( name, age );
        this.school = school;
    }
    void sayHello(){
        System.out.println( "我是學生,我名叫:" + name + ",年齡為:"+ age + ",學校在:" + school );
    }
}
  • 在本例中,在建構函式中呼叫了一個動態繫結的方法sayHello(),這時,會使用哪個方法被覆蓋的定義,而這時物件還沒有完全構建好,所以,School還沒有賦值
  • 因此,可能的話,在構建器中避免呼叫任何方法,用盡可能簡單的方法使物件進入就緒狀態
  • 唯一能夠安全呼叫的是具有final屬性的方法