1.繼承的概念&作用
在Java中,繼承是面向對象編程的三大基本特性之一(還有封裝和多態),允許一個類(子類/繼承類)繼承另一個類(父類/基類)的屬性和方法
繼承的核心目的是:
- 1.子類能夠在不改變父類原有特性的基礎上進行擴展
- 2.實現代碼的復用和建立類之間的層次關系
在我們現有的知識儲備基礎上,如果要抽象出狗和貓,代碼就要這么些:
但我們不難發現,在上述抽象狗和貓的過程中,有部分代碼是重合的。這是因為狗和貓同屬于動物,都有名字、毛色和年齡,都會睡覺。那么我可以定義一個Animal類來對這些相同的代碼(共性)進行抽取,然后讓Dog和Cat類來繼承Animal類中的屬性
2.繼承的語法格式
要實現類之間的繼承關系,需要借助extends關鍵字
修飾符 class 子類類名 extends 父類類名{
//其他代碼
}
注意:
- 1.父類中的所有成員變量和方法都會被子類繼承(即使是private修飾的成員也會被繼承)
- 2.子類在繼承父類原有是特性的基礎上,必須要添加屬于自己的特性(對父類做出擴展),否則沒有繼承的必要
3.如何訪問父類中的成員
3.1 訪問父類中的成員變量
3.1.1 當父類和子類不存在同名變量時
使用this關鍵字就能訪問子類對象中的所有變量
3.1.2 當父類和子類存在同名變量時
注意:
- 1.當在子類對象內部訪問成員變量時,優先訪問自己的成員變量
- 2.如果自己沒有,就從父類繼承的成員變量中查找;如果父類中也沒有,就報錯
- 3.當父類和子類中存在同名變量時,優先訪問子類自己的
如何訪問父類中的同名變量?
下面講到super關鍵字再說
3.2 訪問父類中的成員方法
當訪問父類和子類中的不同名方法時:
- 1.優先訪問子類自己的方法
- 2.如果子類沒有該方法,從父類中查找;如果父類也沒有,報錯
當訪問父類和子類中的同名方法時:
- 3.如果父類和子類的同名方法構成重載,按照調用調用方法時傳遞的參數列表進行匹配
如果父類和子類的方法不僅方法名一樣,參數列表也一樣呢?
此時父類和子類的方法之間構成了重寫。重寫的方法也可以通過super關鍵字來訪問。至于重寫是什么?以及它們之間的調用關系等到講多態的時候再介紹
4.super關鍵字
4.1 使用super訪問父類的成員
在Java中,super關鍵字用于在子類中引用其父類的成員。以上面的dog對象為例,super的訪問范圍如下:
所以在父類和子類中出現同名成員變量時,如果想要訪問父類的同名變量就需要借助super關鍵字
如果想要訪問父類和子類中方法名一樣,參數列表也一樣的成員方法時,也可以借助super關鍵字
4.2 super&this的共性和區別①
共性:
- 1.都屬于Java中的關鍵字
- 2.都只能在非靜態方法中訪問非靜態的方法和變量
區別:
- 1.this表示當前對象的引用,當前對象就是調用實例方法的對象;super是指向 當前對象中 從父類繼承的成員方法和變量 的引用
- 2.從訪問范圍來看,this可以訪問當前對象中的多有成員,但是super只能訪問當前對象中從父類繼承的成員
5.構造方法&初始化順序
5.1 父類和子類的構造關系和執行順序
當創建一個子類對象時,Java會先調用父類的構造方法對父類的成員變量進行初始化,在父類初始化完畢后再調用子類的構造方法對子類的成員變量進行初始化(先有父再有子)。而在子類的構造方法中調用父類的構造方法也需要借助super關鍵字
即使調用父類的無參構造方法,在子類的構造方法中也必須要顯式地寫出super
- super語句必須放在構造方法中的第一行
5.2 super&this的區別②
- 1.在構造方法中,this(…)用于調用本類構造方法,super(…)用于調用父類構造方法。this(…)和super(…)都必須放在構造方法中的第一句,所以在構造方法中this(…)和super(…)不能同時存在
- 2.在子類構造方法中一定存在super(…)的調用(因為父類會默認生成無參構造方法),但是this(…)用戶不寫就沒有
5.3 初始化順序
在上篇JavaSE(7)——類和對象(二)中介紹了三種代碼塊的作用和執行順序。
- 1.實例代碼塊一般用于初始化實例成員變量,靜態代碼塊一般用于初始化靜態成員變量
- 2.靜態代碼塊最先執行且在整個類的聲明周期中只會執行一次;實例代碼塊比構造方法先執行,每實例化一個對象都會執行實例代碼塊
當對象之間引入了繼承關系時,父類和子類的代碼塊和構造方法的執行順序是怎么的呢?
public class Father {//public Father(){System.out.println("父類的無參構造方法");}//{System.out.println("父類的實例代碼塊");}//static {System.out.println("父類的靜態代碼塊");}
}
public class Son extends Father {//public Son(){super();System.out.println("子類的無參構造方法");}//{System.out.println("子類的實例代碼塊");}//static {System.out.println("子類的靜態代碼塊");}
}
public class Test {//public static void main(String[] args) {Son son = new Son();}
}
執行結果:
父類的靜態代碼塊
子類的靜態代碼塊
父類的實例代碼塊
父類的無參構造方法
子類的實例代碼塊
子類的無參構造方法
6. 訪問限定修飾符——protected(受保護的)
被聲明為protected的成員變量/方法,可以被同一個包中的任意類訪問,也可以被其他包中的子類訪問
注意一:
protected成員的訪問權限是基于類層級結構(繼承)和包結構的,而不是對象的引用
要想訪問父類的protected成員只能在子類內部,無法在外部包的非子類中通過子類的引用來訪問
注意二:
在子類中,只能通過子類自己的引用來訪問父類的protected成員
;無法在子類中通過其他子類的引用來訪問父類的protected成員
6.final關鍵字
在Java中,final關鍵字主要用于限制類、方法和變量的可變性和可繼承性
6.1 final修飾類
表示該類不能被繼承
6.2 final修飾成員方法
表示該方法不能被重寫
重寫的概念下篇博文再介紹
6.3 final修飾變量
final修飾成員變量:定義成員變量的同時必須進行初始化
final修飾局部變量:
- 1.定義局部變量的同時進行初始化,之后無法修改該變量的值
-2.定義局部變量時未初始化,在第一次初始化之后,無法再修改該變量的值