第七天 構造器和super關鍵字
在開發的過程中,創建對象的同時要明確對象的屬性值,比如員工入職就要明確讓他的姓名,年齡等.怎麽解決呢就需要構造方法
構造方法:是一個類的成員方法,它的名稱與類的名稱相同,聲明類的一個對象時,會自動調用 構造方法,構造方法用於初始化對象
構造方法的定義:
格式
修飾符 構造方法名(參數列表){ }
體現:
名稱必須與類名一致,
沒有返回值類型,因為他用來構造對象,對象構造完,方法就執行結束
不能被static、final、synchronized、abstract和native修飾。
構造方法是可以被private修飾的,作用其他程序無法創建該類的對象.
舉例
class Person { // Person的成員屬性age和name private int age; private String name; // Person的構造方法,擁有參數列表 Person(int a, String nm) { // 接受到創建對象時傳遞進來的值,將值賦給成員屬性 age = a; name = nm; } }
特點:在new對象的時候自動執行.只要是構造方法默認第一行都是super();Java體系在設計,定義了一個所有對象的父類Object
默認添加的構造方法:編譯的時候,javac 系統會自動檢測類中是否有構造方法,如果沒有 編譯器會自動添加一個構造方法,比如上面的例子,編譯器添加一個 無參數的構造方法public person(){}
構造方法的調用賦值:構造方法是系統自動調用的,不需要手動調用
普通方法不能調用構造方法
構造方法的重載:
與普通方法一樣;
class Person { private int age; private String name; // 私有無參數的構造方法,即外界不能通過new Person();語句創建本類對象 private Person() { } // 多個構造方法是以重載的形式存在 Person(int a) { age = a; } Person(String nm, int a) { name = nm; age = a; } }
構造方法與一般煩那個發的異同
1.格式不同
構造方法 : 修飾符 類名(參數類型 參數 ...){
初始化成員變量
}
一般方法: 需要有返回值類型
2.作用不同
構造方法一般用來給成員變量初始化;
一般方法根據需求而定;
3.調用方式不同
構造方法創建對象時調用, 或者this() super() 語句調用
普通方法需要對象調用或者靜態方法直接調用靜態方法.
4.執行不同
構造方法在對象創建時就執行了,而且只執行一次。
一般方法是在對象創建後,需要使用時才被對象調用,並可以被多次調用。
This在構造方法之間的調用
一般方法可以通過方法名實現方法之間的調用,真對構造方法,無法這樣做.
這個時候就需要借助this關鍵字來實現,來減少代碼的復制,增大代碼的可讀性.
格式:this(參數列表);
This();必須在構造方法第一行,初始化動作要最先執行
class Person { // Person的成員屬性 private int age; private String name; // 無參數的構造方法 Person() { } // 給姓名初始化的構造方法 Person(String nm) { name = nm; } // 給姓名和年齡初始化的構造方法 Person(String nm, int a) { // 由於已經存在給姓名進行初始化的構造方法 name = nm;因此只需要調用即可 // 調用其他構造方法,需要通過this關鍵字來調用 this(nm); // 給年齡初始化 age = a; } }
如果構造器參數有多個怎麽辦?比如說,人有姓名、性別、年齡、體重、身高、出生年月、出生地址......這種情況在做項目中必然是會遇到的,就算開始沒有遇到,隨著項目的需要,也是需要可擴展。這個時候就需要Java高效編程之Builder模式.
Super關鍵字
有人任務super和this是類似的概念 實際上這樣比較不恰當 這是因為super不是一個對象的引用,不能將super 的值賦給另一個變量 他只是指示編譯器調用超類的方法的特殊關鍵字
作用 兩個1構造方法中的使用
2 和this差不多,當父類子類中的成員變量或方法與父類中的成員變量或方法同 名,引用父類中的成員.
子父類中構造方法的調用
創建子類對象時,父類的構造方法會先執行,因為所有的構造方法的第一行有默認 的隱式super();語句
格式:
(調用本類中的構造方法this(實參列表);
調用父類的構造方法:
Super();
Super(參數)
子類構造方法會有一個默認添加的構造方法
public class Student extends Person { public Student(){ super(); } }
為什麽子類對象創建都要訪問父類中的構造方法呢
因為子類繼承了父類的內容,所以創建對象時,必須要先看著父類是如何對其內容進行初始化的.子類默認會調用父類的無參構造, 但如果父類沒有無參構造,子類的構造方法繼續調用父類的無參構造就會報錯。因此子類構造方法的第一行需要調用父類的構造方法,既可以調用父類的無參構造,也可以調用父類的有參構造,這樣語法上就不會報錯。
當父類沒有空參構造方法時,子類的構造方法必須有顯示的super語句,指定要訪問的符有參數構造方法
構造方法的第一行寫this還是super
This()是調用本類的構造方法,super是調用父類的構造方法,兩條語句不能同時存在我們要做的就是保證所有的構造方法能調用到父類的構造方法
如果子類的構造方法第一行寫了this調用了本類其他構造方法,那麽super調用父類的語句還有嗎?
這時是沒有的,因為this()或者super(),只能定義在構造方法的第一行,因為初始化動作要先執行。
無論如何,子類的構造方法,直接或間接必須調用到父類的構造方法
在子類中的成員變量或方法與父類中的成員變量或方法同名,引用父類中的成員.
class Father { public int num = 2; Father() { getNum(); } public void getNum() { System.out.println("父類getNum"+this.num); } } class Son extends Father { public int num=4; public Son() { super(); super.getNum(); System.out.println("子類構造函數中"+num); } public void getNum() { System.out.println("子類getNum方法"+num); } } public class Demo { public static void main(String[] args) { new Son(); } }
結果
子類getNum方法0
父類getNum2
子類構造函數中4
new son();先執行子類構造器,構造器裏先執行父類的構造器,父類構造器調用了getnum方法
為什麽調用的是子類的呢 因為方法已經被子類覆蓋(隱藏)掉了,這個時候打印num也應該打印子類的num而這時num的值還沒始化為4所以還是0 第一句
之後用super.名調用了父類自己的getnum 輸出第二句
最後子類自己的構造方法的最後一句話
第七天 構造器和super關鍵字