JAVA基礎01-繼承關係總結
- 繼承的概念:
繼承在本職上是特殊——一般的關係,即常說的is-a關係。子類繼承父類,表明子類是一種特殊的父類,並且具有父類所不具有的一些屬性或方法。
- 繼承中的初始化順序:
從類的結構上而言,其內部可以有如下四種常見形態:屬性(包括類屬性和例項屬性)、方法(包括類方法和例項方法)、構造器和
初始化塊(包括類的初始化塊和例項的初始化塊)。對於繼承中的初始化順序,又具體分為類的初始化和物件的初始化。
類初始化:
在jvm裝載類的準備階段,首先為類的所有類屬性和類初始化塊分配記憶體空間。並在類首次初始化階段中為其進行初始化,類屬性和類初始化塊之間
的定義時的順序決定了其初始化的順序。若類存在父類,則首先初始化父類的類屬性和類初始化塊,一直上溯到Object類最先執行。
物件初始化:
在new建立物件時,首先對物件屬性和初始化塊分配記憶體,並執行預設初始化。如果存在父類,則先為父類物件屬和初始化塊先分配記憶體並執行初始化。
然後執行父類構造器中的初始化程式,接著才開始對子類的物件屬性和初始化塊執行初始化。
注:
- 在物件初始化階段,屬性和方法均針對子類可以從父類繼承過來的屬性和方法而言,一般而言,都是針對父類中非private而言的。
因為private修飾的為父類所特有的,子類沒有繼承過來,當new子類時,無須為其分配空間並執行初始化。當然了,父類的構造器子類也是不繼承過來的,
但構造器另當別論。
- 類的初始化只執行一次,當對同一個類new多個物件時,類屬性和類初始化塊只初始化一次。
3.繼承中的隱藏:
隱藏含義:實際上存在,但是對外不可見。
Java類具有三種訪問控制符:private、protected和public,同時當不寫這三個訪問控制符時,表現為一種預設的訪問控制狀態。因此,一共具有四種訪問控制級別。
具體訪問控制表現如下:
private修飾的屬性或方法為該類所特有,在任何其他類中都不能直接訪問;
default修飾的屬性或方法具有包訪問特性,同一個包中的其他類可以訪問;
protected修飾的屬性或方法在同一個中的其他類可以訪問,同時對於不在同一個包中的子類中也可以訪問;
public修飾的屬性或方法外部類中都可以直接訪問。
當子類繼承父類,子類可以繼承父類中具有訪問控制權限的屬性和方法(一般來說是非private修飾的),對於private修飾的父類所特有的屬性和方法,子類是不繼承過來的。
當子類需要改變繼承過來的方法時,也就是常說的重寫父類的方法。一旦重寫後,父類的此方法對子類來說表現為隱藏。以後子類的物件呼叫此方法時,都是呼叫子類重寫後
的方法,但子類物件中想呼叫父類原來的此方法時,可以通過如下兩種方式:
1.將子類物件型別強制轉化為父類型別,進行呼叫;
2.通過super呼叫。
同樣的,如果在子類中定義父類中相同名稱的屬性時,父類屬性在子類中表現為隱藏。
4.繼承中的this和super:
構造器中的this表示當前正在初始化的物件引用,方法中的this表示當前正在呼叫此方法的物件引用。this具體用法表現在一下幾個方面:
1.當具多個過載的構造器時,且一個構造器需要呼叫另外一個構造其,在其第一行使用this(param)形式呼叫,且只能在第一行;
2.當物件中一個方法需要呼叫本物件中其他方法時,使用this作為主調,也可以不寫,實際上預設就是this作為主調;
3.當物件屬性和方法中的區域性變數名稱相同時,在該方法中需要顯式的使用this作為主調,以表示物件的屬性,若不存在此問題,可以不顯式的寫this。
其實,其牽涉到的一個問題就是變數的查詢規則:先區域性變數 => 當前類中定義的變數 => 其父類中定義的可以被子類繼承的變數 => 父類…
super表示呼叫父類中相應的屬性和方法。在方法中,若需要呼叫父類的方法時,也一定要寫在第一行
- 繼承與組合:
從單純的實現效果上看,繼承和組合都能達到同樣的目的。並且都是實現程式碼複用的有效方式。
但在一般性的概念層次中,兩者具有較為明顯的差別。
繼承表現為一般——特殊的關係,子類是一個特殊的父類,是is-a的關係。父類具有所有子類的一般特性。
組合表現為整體——部分關係,即has-a關係。在組合中,通過將“部分”單獨抽取出來,形成自己的類定義,並且在“整體”
這個類定義中,將部分定義為其中的一個屬性,並通過get和set方法,以此可以呼叫“部分”類中的屬性和方法。
public class superClass {
protected String name ="super_rabbit1";
public superClass() {
System.out.println("super_constructor");
}
public superClass(String name ) {
System.out.println(name);
}
public void call(){
System.out.println("super_rabblit2");
}
}
public class subClass extends superClass{
public String name = "sub_rabbit1" ;
public subClass(){
super("123");
}
public subClass(String name ){
System.out.println(name);
}
public void call(){
System.out.println("sub_rabbit2");
}
public static void main(String[] args) {
subClass sub1 = new subClass();
sub1.call();
System.out.println(sub1.name);
superClass sub2 = new superClass();
sub2.call();
System.out.println(sub2.name);
superClass sub3 = new subClass();
sub3.call();
System.out.println(sub3.name);//欄位不存在覆蓋
}
}
結果:
123
sub_rabbit2
sub_rabbit1
super_constructor
super_rabblit2
super_rabbit1
123
sub_rabbit2
super_rabbit1
筆者水平有限,若有錯漏,歡迎指正,摘自https://www.cnblogs.com/lwbqqyumidi/p/3509992.html