類初始化與例項初始化
阿新 • • 發佈:2021-07-02
類初始化與例項初始化
類初始化
- 一個類要建立例項首先要先載入並初始化該類
- main方法所在的類需要先載入和初始化
- 一個子類要初始化需要先初始化父類
- 一個類初始化就是執行<clint>()方法
例項初始化
例項初始化就是執行
- <init>()方法可能過載有多個,有幾個構造器就有幾個 <init>()方法
- <init>()方法由非靜態例項變數顯示賦值程式碼和非靜態程式碼塊、對應構造器程式碼組成
- 非靜態例項變數顯示賦值程式碼和非靜態程式碼塊、對應構造器的程式碼最後執行
- 每次創造例項物件,呼叫對應構造器,執行的就是對應的 <init>()方法
- <init>()方法方法的首行執行的是super()或super(實參列表),即對應父類的 <init>()方法
方法重寫
- 哪些方法不可以被重寫
- final方法
- 靜態方法
- private等子類中不可見方法
- 物件的多型性
- 子類如果重寫了父類的方法,通過子類物件呼叫的一定是子類重寫過的程式碼
- 非靜態方法預設的呼叫物件時this
- this物件在構造器或者說<init>中就是正在建立的物件
- 方法重寫與方法過載
- 重寫
要求兩同兩小一大原則, 方法名相同,引數型別相同,子類返回型別小於等於父類方法返回型別, 子類丟擲異常小於等於父類方法丟擲異常, 子類訪問許可權大於等於父類方法訪問許可權。[注意:這裡的返回型別必須要在有繼承關係的前提下比較] - 過載
方法名必須相同,引數型別必須不同,包括但不限於一項,引數數目,引數型別,引數
例題
下列程式執行結果為什麼?
/** *父類初始化<clinit> * (1)j = method(); * (2)父類的靜態程式碼塊 * *父類例項化化<clinit> * (1)super(); * (2)i = test(); * (3)父類的非靜態程式碼塊 * (4)父類的無參構造 */ public class Father{ private int i = test(); private static int j = method(); static{ System.out.print("1"); } Father(){ System.out.print("2"); } { System.out.print("3"); } public int test(){ System.out.print("4"); } public static int method(){ System.out.print("5"); } }
/**
*
*子類初始化<clinit>
* (1)j = method();
* (2)子類的靜態程式碼塊
*
*子類例項化化<clinit>
* (1)super();
* (2)i = test();(多型,子類繼承父類並重寫父類方法時執行)
* (3)子類的非靜態程式碼塊
* (4)子類的無參構造
*/
public class Son extends Father{
private int i = test();
private static int j = method();
static{
System.out.print("6");
}
Father(){
System.out.print("7");
}
{
System.out.print("8");
}
public int test(){
System.out.print("9");
}
public static int method(){
System.out.print("10");
}
public static void main(String[] args){
Son s1 = new Son();
System.out.print();
Son s2 = new Son();
}
}
答案:s1:5 1 10 6 9 3 2 9 8 7 s2:9 3 2 9 8 7