繼承
在已有類的基礎上建立出新的類,新的類擁有父類中訪問修飾符允許訪問的數據和功能,並且可以擴展新的數據和功能。語法格式:class 子類名 extends 父類名{}
任何一個類的頂級父類都是Object類,即使創建一個類沒有使用關鍵字extends繼承任何類,那麼此時默認是繼承Object類的
關鍵字super
1、 在子類中訪問父類的成員例如:
//調用父類中的屬性
super.屬性
//調用父類中的方法
super.方法();
如果父類和子類中的屬性出現同名時,必須使用super.的方式才能訪問父類中的屬性;如果沒有同名衝突,可以省略super,也可以使用關鍵字this.的方式訪問父類中的屬性
2、super([參數列表]) 訪問父類中的構造方法;
如果子類的構造方法中沒有顯示的編寫super([參數列表])訪問父類構造方法,系統默認提供一個訪問父類無參構造的語句(super(););如果自行編寫,必須寫在子類構造方法中的第一行,此時系統將不再提供super();
實例一:演示使用繼承後,創建子類對象時構造方法的執行順序
package characteristic.inherit.create_order;
/**
* 使用extends關鍵字繼承父類Father
* 演示創建子類對象時構造方法執行的順序
* @author 學霸聯盟 - 趙燦
*/
public class Son extends Father{
// 子類私有的屬性name
private String sonName;
// 無參構造方法
public Son() {
// 調用父類的構造方法,必須寫在構造方法中的第一行
super("張三");
System.out.println("Son類的無參構造");
}
// 帶參構造方法
public Son(String name) {
/*
* 不寫也會默認調用父類的無參構造
* 如果父類中寫了帶參構造,而沒有寫無參構造
* 這樣系統不會給父類提供無參構造
* 此時在子類中使用super()就會出錯,而且子類中必須使創建構造方法
* 並在構造方法中用super(參數)去調用父類的構造方法
*/
super();//這句代碼可以省略
System.out.println("Son類的帶參構造,名稱:" + name);
}
public void printFatherProperty() {
// 子類中可以繼承父類中除private修飾以外的成員
//可以使用super.成員
System.out.println(super.defaultProperty);
//當前類沒有屬性和父類屬性重名的情況下,也可以使用this.成員
System.out.println(this.protectedProperty);
//當前類沒有屬性和父類屬性重名的情況下,也可以省略this
System.out.println(publicProperty);
//調用父類的方法同樣可以使用上述三種方式
super.work();
}
}
package characteristic.inherit.create_order;
/**
* 用於演示使用繼承後創建子類對象時構造方法的執行順序
* @author 學霸聯盟 - 趙燦
*/
public class Father {
// 私有屬性name
private String fatherName;
// 聲明四種訪問權限的屬性,用於測試子類中繼承的情況
private String privateProperty = "父類私有的屬性";
String defaultProperty = "父類默認的屬性";
protected String protectedProperty = "父類保護的屬性";
public String publicProperty = "父類公共的屬性";
// 無參構造
public Father() {
System.out.println("Father類的無參構造方法");
}
// 帶參構造
public Father(String name) {
System.out.println("Father類的帶參構造方法,名稱:" + name);
}
// 創建一個工作的方法
public void work() {
System.out.println("父類中工作的方法");
}
}
package characteristic.inherit.create_order;
/**
* 測試繼承
* @author 學霸聯盟 - 趙燦
*/
public class Test {
public static void main(String[] args) {
System.out.println("----- 調用子類的無參構造創建子類對象 -----");
// 調用不同的構造方法創建子類對象
Son son1 = new Son();
System.out.println("----- 調用子類的帶參構造創建子類對象 -----");
Son son2 = new Son("兒子:李四");
son2.printFatherProperty();
}
}
運行結果:
----- 調用子類的無參構造創建子類對象 -----
Father類的帶參構造方法,名稱:張三
Son類的無參構造
----- 調用子類的帶參構造創建子類對象 -----
Father類的無參構造方法
Son類的帶參構造,名稱:兒子:李四
父類默認的屬性
父類保護的屬性
父類公共的屬性
父類中工作的方法
由結果可以看出創建子類Son的對象時,會先執行Father的構造方法,如果子類中沒有寫構造方法或子類的構造方法中沒有顯示的調用父類的某個構造方法,那麼默認會訪問父類的無參構造方法。而Father類沒有寫繼承哪個類,默認是繼承Object類的。
子類中可以訪問父類中的哪些成員,由訪問修飾符規定的權限決定
方法的重寫:@Override
簡單的理解就是在子類中重新編寫從父類中繼承的方法。滿足重寫的條件:
1、子類中和父類中的方法同名(方法名相同)
2、發生在有繼承關係的兩個類中
3、參數列表要相同
4、返回值類型要兼容
5、不可以縮小訪問修飾符,但可以放大訪問修飾符
6、只能重寫訪問修飾符允許訪問的方法
實例二:用於演示子類重寫父類方法後,不同引用指向子類對象時執行的不同結果
package characteristic.inherit.resources;
/**
* 用於演示子類重寫父類方法後,不同引用指向子類對象時執行的不同結果
* @author 學霸聯盟 - 趙燦
*/
public class Father {
//工作的方法
public void work(){
System.out.println("父親在辛苦的工作");
}
//父類中玩的方法
public void play(){
System.out.println("帶着兒子玩");
}
}
package characteristic.inherit.resources;
/**
* 繼承父類Father
* @author 學霸聯盟 - 趙燦
*/
public class Son extends Father{
//子類重寫父類中玩的方法
public void play(){
System.out.println("兒子還小,只能跟着父親玩");
}
//子類中特有的方法
public void study(){
System.out.println("兒子在學習");
}
}
package characteristic.inherit.resources;
/**
* 測試繼承
* @author 學霸聯盟 - 趙燦
*/
public class Test {
public static void main(String[] args) {
// 調用不同的構造方法創建子類對象
Son son = new Son();
//調用從父類中繼承的方法
son.work();
//調用自己的方法
son.play();
son.study();
System.out.println("----- 父類引用指向子類對象 -----");
//父類引用指向子類對象
Father f = new Son();
//使用父類的引用指向子類的對象,可以調用父類自己的方法
f.work();
//調用已經被子類重寫了的方法時,執行的是子類中重寫後的方法
f.play();
}
}
運行結果:
父親在辛苦的工作
兒子還小,只能跟着父親玩
兒子在學習
----- 父類引用指向子類對象 -----
父親在辛苦的工作
兒子還小,只能跟着父親玩
由結果可以看到,子類對象賦值給子類引用(子類變量)時,子類引用可以調用父類中除private修飾以外的成員。當子類對象賦值給父類引用(父類變量:此時存在自動類型轉換,即子類型轉換成父類型),此時父類引用無法使用任何子類中的屬性和子類中獨有的其他方法,調用被子類重寫的方法時,執行的是子類中重寫後的方法總結:1、繼承的優點:有效的複用代碼,很好的解決了代碼冗餘(重複的代碼)的問題。
2、java只支持單根繼承;即只能繼承一個類。
3、創建子類對象時,先執行父類的構造方法,再執行子類的構造方法。默認執行父類的無參構造
4、使用super關鍵字調用父類的構造方法時,必須寫在子類構造方法中的第一行。
5、使用關鍵字super可以訪問父類中訪問修飾符允許訪問的成員
6、如果子類中的屬性和父類中的屬性沒有重名,也可以使用this或省略this的方式訪問父類中的屬性
7、子類引用指向子類對象時,子類引用可以調用自身訪問修飾符允許訪問的成員,和從父類繼承的成員。
8、父類引用指向子類對象時,父類引用可以調用自身訪問修飾符允許訪問的成員,和子類中重寫父類的方法,但無法調用子類中獨有的方法
9、只有方法存在重寫,屬性不存在重寫