大家可以關註作者的賬號,關註從零開始學Java筆記文集。也可以根據目錄前往作者的博客園博客進行學習。本片文件將基於黑馬程式員就業班視頻進行學習以及資料的分享,並記錄筆記和自己的看法。歡迎大家一起學習和討論。 "【從零開始學Java筆記】目錄" 什麼是繼承? 繼承就是子類繼承父類的特征和行為,使得子類 ...
大家可以關註作者的賬號,關註從零開始學Java筆記文集。也可以根據目錄前往作者的博客園博客進行學習。本片文件將基於黑馬程式員就業班視頻進行學習以及資料的分享,並記錄筆記和自己的看法。歡迎大家一起學習和討論。
【從零開始學Java筆記】目錄
什麼是繼承?
繼承就是子類繼承父類的特征和行為,使得子類對象(實例)具有父類的實例域和方法,或子類從父類繼承方法,使得子類具有父類相同的行為。
簡單的說就是多個類有相同的成員變里和成員方法,為了避免代碼的重覆,可以先寫一個父類,包含共同的屬性,然後再由子類繼承。
關鍵字:extends
下麵舉個例子:
- 不使用繼承
class GuanYu{
String name;
int age;
String address;
public void win() {
System.out.println("關羽贏了!");
}
public void lose() {
System.out.println("關羽輸了!");
}
}
class LvBu{
String name;
int age;
String address;
public void win() {
System.out.println("呂布贏了!");
}
public void lose() {
System.out.println("呂布輸了!");
}
}
可以看出無論是關羽還是呂布都擁有成員變數:姓名,年齡和地址
和成員方法:贏和輸
。如果想寫一百個武將,十分繁瑣。所以使用繼承,寫一個父類,先尋找他們的共性,那就是他們都是人,所以寫一個people
類,包含他們共同的屬性和方法。如下:
class Person{
String name;
int age;
String address;
public void win() {
System.out.println("關羽贏了!");
}
public void lose() {
System.out.println("關羽輸了!");
}
}
class GuanYu extends Person{
}
class LvBu extends Person{
}
Java中維承的特點
- Java語言只支持單一繼承,只能繼承一個父類(一個兒子只能有一個親爹)
Java語言支持多層繼承(一個兒子可以有一個親爹, 還可以有一個親爺爺)
繼承中成員變數的特點
- 子類只能獲取父類非私有成員
子父類中成員變數的名字不一樣 直接獲取父類的成員變里
子父類中成員變數名字是一樣的獲取的是子類的成員變數
class GuanYu{
private String wifeName = "null";
String name = "GuanYu";
}
class GuanXing extends GuanYu{
String name = "GuanXing";//如果沒有這句,show()輸出GuanYu
public void show() {
// System.out.println(wifename); 子類無法繼承父類的私有變數,報錯
System.out.println(name);//輸出GuanXing
}
給大家出一道題,大家思考一下三個輸出語句的結果,如果能理解基本上就沒什麼問題了
這裡為大家補充一個就近原則:誰離我近我就用誰
如果有局部變數就使用局部變數
如果沒有局部變數,有子類的成員變數就使用子類的成員變數
如果沒有局部變數和子類的成員變數,有父類的成員變數就使用父類的成員變數
啥都沒有,出錯了! ! !|
class GuanYu{
String name = "關羽";
}
class GuanXing extends GuanYu{
String name = "關興";
public void show() {
String name = "關平";
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);
}
super :可以獲取父類的成員變數和成員方法
this:可以獲取當前類的成員變數和成員方法
輸出結果
關平
關興
關羽
繼承中成員方法的特點
和成員變數相似
- 子類中沒有這個方法,調用父類的
子類中重寫了這個方法,調用子類的
重寫和重載的區別
方法的重寫:在子父類當中,子類的方法和父類的完全一樣,子類重寫了父類的方法(覆蓋),當子類重寫了父類的方法之後,使用子類對象調用的就是子類的方法
方法的重載:在一個類中,有多個重名的方法,但是其參數不一樣(參數的個數,參數的類型,參數的順序),和返回值無關
方法重寫的應用場景
- 當父類的方法不能完全滿足子類使用,這個時候子類重寫父類的方法
並可以在方法中使用關鍵字super調用父類的方法,這樣做即可以保有父類的功能,也可以擁有子類持有的功能
這裡給大家舉個例子
class GuanYu{
public void attack() {
System.out.println("拖刀");
}
}
class GuanXing extends GuanYu{
public void attack() {
super.attack();
System.out.println("斬");
}
其實很簡單,關興繼承了父親的攻擊方式,但是在拖刀的前提下加入了斬,使威力更強。這裡為什麼使用super.attack()
為什麼不直接複製過來,這裡可以想象拖刀是一個很複雜的過程,但是我們這裡簡寫,如果關羽攻擊的函數有1000行代碼,調用比複製更方便,也更好看。
方法重寫的註意事項
不能重寫父類私有的方法
許可權必須大於等於父類方法的許可權(瞭解即可)
註解: @ 一般寫在方法、變數、類前面,用來描述方法、變數、類,目的是提高代碼規範
還用剛纔那個例子
class GuanYu{
public void attack() {
System.out.println("拖刀");
}
}
class GuanXing extends GuanYu{
// public void attck() {
// super.attack();
// System.out.println("斬");
// }
public void attack(String a) {
super.attack();
System.out.println("斬");
}
如果我們給子類的方法加一個形參 string a
,或者錯寫成attck()
並不會報錯,但是這個已經不算是方法的重寫了
這時候我們在重寫的代碼前加上@Override,就會報錯。
繼承中構造方法的執行順序
public class ExtendsDemo2 {
public static void main(String[] args) {
GuanYu gy = new GuanYu();
System.out.println("****************");
GuanXing gx = new GuanXing();
}
}
class GuanYu{
public GuanYu() {
System.out.println("這是關羽的無參構造");
}
public GuanYu(int a) {
System.out.println("這是關羽的有參構造");
}
}
class GuanXing extends GuanYu{
public GuanXing() {
System.out.println("這是關興的無參構造");
}
public GuanXing(int a) {
System.out.println("這是關興的有參構造");
}
}
輸出結果
這是關羽的無參構造
****************
這是關羽的無參構造
這是關興的無參構造
為什麼調用子類的無參構造的時候,也會調用父類的無參構造?
在有子父類繼承關係的類中,創建子類的對象,調用子類的構造方法,如果子類構造方法的第一行代碼沒有調用父類的構造方法,則會預設的調用父類的無參構造
我們可以使用super( )在子類構造方法的第一行中調用父類的構造方法
class GuanXing extends GuanYu{
public GuanXing() {
//super(1); //測試1
//this(2); //測試2
System.out.println("這是關興的無參構造");
}
public GuanXing(int a) {
System.out.println("這是關興的有參構造");
}
可以分別取消測試1和測試2的註釋,再運行,看看結果。
為什麼會有這個設定呢?因為必須先執行父類的構造,要先給父類的成員變里進行初始化,子類可能會使用到。
this和super的區別
this:當前對象的引用
調用子類的成員變數
調用子類的成員方法
在子類的構造方法第一行調用子類其他構造方法
super:子類對象的父類引用
調用父類的成員變數
調用父類的成員方法
在子類的構造方法第一行調用父類的構造方法
繼承的優缺點
優點
- 提高了代碼的復用性
- 提高了代碼的可維護性
缺點
- 類的耦合性增強了
- 開發的原則:高內聚低耦合
- 內聚:就是自己完成某件事情的能力
- 耦合:類與類的關係
通俗易懂的來說就是繼承可以只通過修改父類的屬性來實現子類屬性的同步修改,這樣會很方便。例如,奧迪,寶馬都是汽車的子類,如果想讓所有品牌汽車的價格增加15%,只需要再父類裡面進行操作即可。但是同時也會出現問題,父類的屬性進行修改,子類的屬性必定進行修改,但有時或出現錯誤。例如刪掉增加15%的價格,所有的品牌都會自動刪除,如果有一些其他和價格有關的方法就會出現錯誤。其實這樣就是高耦合的表現,類與類之間關係十分緊密,牽一發而動全身。