第7章繼承
理解繼承的基礎知識、調用超類構造函數、使用super訪問超類成員、創建多級類層次結構、瞭解何時調用構造函數、理解子類對象的超類引用、重寫方法、使用重寫方法實現動態方法分配、使用抽象類、使用final、瞭解Object類
繼承的基礎知識
Java不支持一個子類繼承多個超類。但是,可以創建類的繼承層次結構,其中的一個子類可以稱爲另一個子類的超類。
構造函數與繼承
什麼樣的構造函數負責創建子類對象呢?
是超類構造函數還是子類構造函數?
超類的構造函數構造超類部分,子類的構造函數構造對象的子類部分。
因爲超類並不知道或無權訪問子類的任何元素。
當子類和超類都定義構造函數時,這種情況下的兩個構造函數都要執行。這種情況下可以使用另外一個關鍵字。super
super的兩種用法:第一種調用超類的構造函數,第二種用於訪問被子類成員隱藏的超類成員。
使用super調用超類構造函數
super()必須是在子類中執行的第一條語句。
class A1{
private int a;
A1(){
a=0;
}
A1(int aa){
a=aa;
}
public int getA1(){
return a;
}
public void setA1(int a1){
a=a1;
}
}
class B1 extends A1{
private int b;
B1(int bb){
super();
b=bb;
}
B1(int aa,int bb){
super(aa);
b=bb;
}
public int getB1() {
return b;
}
public void setB1(int b) {
this.b = b;
}
}
這兩種形式都可以。
使用super訪問超類成員
這種形式多用於子類的成員隱藏了超類中同名成員的情況。
class A1{
int a;
}
class B1 extends A1{
private int a;
B1(int aa,int bb){
super.a=aa;
a=bb;
}
}
何時調用構造函數
當創建超類對象時,首先執行哪一個構造函數,是子類的構造函數還是超類的構造函數?
構造函數的調用是按照繼承的順序,從超類到子類來進行的。
超類引用和子類對象
1、子類對象的引用可以賦值給超類引用變量
2、哪些成員可以訪問是由引用變量的類型(而不是它引用的對象的類型)決定的。當一個子類對象的引用賦值給超類引用變量時,只有權訪問超類的成員。
方法重寫
當子類中的方法和超類中的方法有一樣的返回值類型和簽名時,就說子類的方法重寫了超類中的方法。
在子類中調用被重寫的方法時,總是調用子類中定義的方法,超類中定義的方法被隱藏。
上面提到哪些成員可以訪問是由引用變量的類型決定的,而不是它引用的對象的類型。把子類對象的引用賦值爲超類引用變量時,如果出現了方法重寫,超類引用變量調用該重寫方法時,調用的是子類的方法。
class A1{
int a;
void show(){
System.out.println(a);
}
}
class B1 extends A1{
private int b;
B1(int aa,int bb){
super.a=aa;
b=bb;
}
void show(){
//super.show();
System.out.println(b);
}
}
public class C1 {
public static void main(String[] args){
A1 b = new B1(1,2);
b.show();
}
}
重寫方法是Java實現多態性的“單接口,多方法”的又一種方式。
重寫的方法支持多態性
方法重寫組成了Java最強大的概念之一:動態方法分配。
動態方法分配是一種機制,通過該機制對一個被重寫方法的調用會在運行時解析,而不是在編譯時解析。
我們再從超類引用變量可以引用子類對象這一重要的原理開始討論。Java利用這一事實解決了運行時對重寫方法的調用。辦法如下:當通過超類引用調用被重寫的方法時,Java會根據在調用發生時引用對象的類型來判斷所要執行的方法。因此,這種判斷髮生在運行時。當引用不同類型的對象時,將調用被重寫的方法的不同版本。換句話說,是被引用對象的類型(而不是引用變量的類型)決定了所要執行的被重寫方法。
使用抽象類
有時,需要創建這樣一個超類:該超類只定義了一個所有子類共享的一般形式,至於實現的細節則交給每一個子類去填充。這樣的類決定了子類必須實現的方法的本質,而它自己則不提供其中一個或多個方法的實現。
抽象方法是通過指定abstract類型修飾符來創建的。抽象方法沒有內容,一次無法被超類實現,這樣,子類就必須重寫它。
使用final
如果要防止方法重寫或類的繼承,需要使用關鍵字final
使用final防止重寫
final void meth(){}
在超類的方法前加上關鍵字final就可以防止子類對該方法重寫。
使用final防止繼承
final class A{}
在類前加上final關鍵字,就可以防止該類被繼承
對數據成員使用final
如果在類的變量名前使用final,它的值在程序的生命週期內就不能改變,允許爲變量賦初值。final常量,習慣使用大寫的標識符。
Object類
Object類是所有類的隱式超類。