Java構造器

構造器定義

      構造器是用來初始化類實例。在對象編程語言中,一般在定義了一個類型之後,爲了能使用它,必須把這個類型具體化,也就是指定爲一個具體的對象。而構造函數就是從定義出發,建立與定義相對應的對象。用計算機語言來說,光有定義是不能使用,必須通過構造函數來分配內存空間給可使用的對象。

構造器的聲明語法

<作用域> <類名> (<參數列表>){
        <方法體>
}

構造器的使用規則

  • 構造器的名稱始終與其類名相同
  • 一個類可以有多個構造器
  • 構造器可以有0、1個或多個參數
  • 構造器始終使用new關鍵字進行調用
  • 構造器沒有返回值

構造方法與成員方法的區別

  • 修飾符不同
    構造方法只能使用public、private、protected訪問修飾符,而不能使用static、final、synchronized、abstract等非訪問修飾符。這是因爲構造方法用於初始化一個實例對象,所以static修飾是沒有任何意義的;多個線程不會同時創建內存地址相同的同一個對象,所以synchronized修飾沒有意義;構造方法不能被子類繼承,所以final和abstract修飾沒有意義。
  • 返回值不同
    構造方法沒有返回值。
  • 構造方法名與類名相同。

缺省構造器

  • 每個類至少有一個構造器
  • 如果你沒有手工編寫一個構造器,則系統在編譯時自動添加一個缺省構造器
public class A {

    public static void main(String[] args) {
        A a = new A();//調用系統默認的無參構造器
    }
}
  • 一旦自己定義了自己的構造函數java就會收回自己的默認構造函數,因此建議自己要書寫無參構造函數。
public class A {
    public A(String name){
        System.out.println(name);
    }
    public static void main(String[] args) {
        //A a = new A();//報錯,因爲沒有相應的無參構造函數的定義
        A a2 = new A("a2");//輸出結果爲:a2
    }
}

構造器不能被繼承

  • 子類繼承父類所有的成員方法和成員變量
  • 但子類不繼承父類的構造器。

調用其他構造器

  • 調用父類構造器用super()方法
    使用super可以調用父類的構造器
public class A {
    public A(){
        System.out.println("A--無參構造器");
    }
    public A(String name){
        System.out.println("A--有參構造器:"+name);
    }
}

public class B extends A{
    public B(){
        super();
        System.out.println("B--無參構造器");
    }
    public B(String name){
        super(name);
        System.out.println("B--有參構造器:"+name);
    }
    public static void main(String[] args) {
        B b1 = new B();
        System.out.println("--------------");
        B b2 = new B("b2");
    }
}
//輸出結果爲:
/*
A--無參構造器
B--無參構造器
--------------
A--有參構造器:b2
B--有參構造器:b2
             */

         使用super也可以在成員方法中調用父類的成員方法

public class A {
    public void method(){
        System.out.println("method:A");
    }
}

public class B extends A{
    public void method(){
        System.out.println("method:B");
        super.method();
    }
    public static void main(String[] args) {
        B b1 = new B();
        b1.method();        
    }
}

//運行結果爲:
//A--無參構造器
//B--無參構造器
  • 調用當前類構造器用this()方法
    this在構造器中可以調用其他的構造器,但必須在第一行且只能調用一次。
public class A {
    public A(){
        System.out.println("無參構造器");
    }
    public A(String name){
        this();
        System.out.println("有參構造器:"+name);
    }
    public static void main(String[] args) {
        A a2 = new A("a2");//有參構造器
    }
}
//運行結果爲:
//無參構造器
//有參構造器:a2

         另外,this關鍵字也代表當前的實例對象,因此this關鍵字不能用於static方法中。

public void setName(String name) {
    this.name = name;
}
  • 子類默認調用父類的無參構造器,如果父類自己定義了有參構造器而沒有定義無參構造器,那麼就會報錯。但這時如果子類顯示的調用父類的有參構造器,就不會報錯。
public class A {
    public A(String name){
        System.out.println("A--有參構造器:"+name);
    }
}

public class B extends A{
    public B(String name){
        super(name);
        System.out.println("B--有參構造器:"+name);
    }
    public static void main(String[] args) {
        B b2 = new B("b2");
    }
}
//輸出結果爲:
//A--有參構造器:b2
//B--有參構造器:b2

         從上例也可以看出先初始化父類的構造器,再初始化子類的構造器。

初始化順序問題

初始化順序:
1. 靜態成員首先被初始化且只初始化一次。
2. 父類構造器被初始化。
3. 實例變量被初始化。
4. 本類構造方法被初始化。

由下述代碼可得上述結論

public class A {
    public A(){
        System.out.println("A--無參構造器");
    }
    public A(String name){
        System.out.println("A--有參構造器:"+name);
    }
}

public class B extends A{
    A a2 = new A("a2");
    static A a3 = new A();
    public B(String name){
        super(name);
        System.out.println("B--有參構造器:"+name);
    }
    public static void main(String[] args) {
        B b1 = new B("b1");
        B b2 = new B("b2");
    }
}

//運行結果爲:
/**
    A--無參構造器
    A--有參構造器:b1
    A--有參構造器:a2
    B--有參構造器:b1
    A--有參構造器:b2
    A--有參構造器:a2
    B--有參構造器:b2
*/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章