Java筆記丨12 類的繼承
繼承
繼承(inheritance)是面向物件程式設計中最為重要的特徵之一
子類(subclass),父類或超類(superclass)
父類包括所有直接或間接被繼承的類
Java支援單繼承:一個類只能有一個直接父類
子類繼承父類的狀態和行為
可以修改父類的狀態或過載父類的行為
可以新增新的狀態和行為
好處
可以提高程式的抽象程度
實現程式碼重用,提高開發效率和可維護性
派生子類
Java中的繼承是通過extends
Class Student extends Person{
…
}
如果沒有extends子句,則預設該類為java.lang.Object的子類
所有類都是通過直接或間接地繼承java.lang.Object得到的
繼承關係
繼承關係在UML圖中,是用一個箭頭來表示子類與父類的關係的
相當於is a
類Student從類Person繼承,定義如下:
class Student extends Person{ String school; int score; Boolean isGood(){ return score>80; } }
欄位
1.欄位的繼承
子類可以繼承父類的所有欄位
Student自動具有Person的屬性(name,age)
2.欄位的隱藏
子類重新定義一個與從父類那裡繼承來的域變數完全相同的變數,成為域的隱藏。域的隱藏在實際程式設計中用得較少。
3.欄位的新增
在定義子類時,加上新的域變數,就可以使子類比父類多一些屬性。如:
class Student extends Person{
String school;
int score;
}
方法
1.方法的繼承
父類的非私有方法也可以被子類自動繼承。如Student自動繼承Person的方法sayHello和isOlderThan
2.方法的覆蓋(Override)(修改)
子類也可以重新定義與父類同名的方法,實現對父類方法的覆蓋(Override)
@Override
@Override//JDK1.5以後可以用這個註記來表示(不用也是可以的)
void sayHello(){
System.out.println(“Hello! My name is ”+name+ “. My school is ”+school);
}
通過方法的覆蓋,能夠修改物件的同名方法的具體實現方法
3.方法的新增
子類可以新增一些新方法,以針對子類實現相應的功能
如,在類Student中,加入一個方法,對分數進行判斷:
boolean isGoodStudent(){
return score>=90;
}
4.方法的過載
一個類中可以有好幾個同名的方法,這稱為方法的過載(Overload)。同時,還可以過載父類的同名方法。與方法覆蓋不同的是,過載不要求引數型別列表相同。過載的方法實際是新加的方法。
如,在類Student中,過載一個名為sayHello的方法:
void sayHello(Student another){
System.out.println(“Hi!”);
if(school.equals(another.school))
System.out.println(“Schoolmates”);
}
super的使用
1.使用super訪問父類的域和方法
注意:正是由於繼承,使用this可以訪問父類的域和方法。但有時為了明確地指出父類的域和方法,就要用關鍵字super。
例如:父類Student有一個域age,在子類Student中用age,this.age,super.age,來訪問時完全一樣的:
void testThisSuper(){
int a;
a=age;
a=this.age;
a=super.age;
}
當然,使用super不能訪問在子類中新增的域或方法。
有時需要使用super以區別同名的域或方法
- 使用super可以訪問被子類所隱藏了的同名變數
- 又如,當覆蓋父類的同名方法的同時又要呼叫父類,就必須使用super。如:
void sayHello(){
super.sayHellpo();
System.out.println(“My school is ”+school);
}
在覆蓋父類的方法的同時,又利用已定義好的父類的方法
2.使用父類的構造方法
構造方法是不能繼承的
比如,父類Person有一個構造方法Person(String,int),不能說子類Student也自動有一個構造方法Student(String,int)。
但是,子類在構造方法中,可以用super來呼叫父類的構造方法
Student(String name, int age, String school){
super(name,age);
this.school=school;
}
使用時,super()必須放在第一句
有關構造方法更詳細的討論,參見後面的筆記。
父類物件與子類物件的轉換
類似於基本資料型別資料之間的強制型別轉換,存在繼承關係的父類物件和子類物件之間也可以在一定條件下相互轉換。
1.子類物件可以被視為其父類物件的一個物件
如一個Student物件也是一個Person物件
2.父類物件不能被當做其某一個子類的物件
3.如果一個方法的形式引數定義的是父類物件,那麼呼叫這個方法時,可以使用其子類物件作為實際引數
4.如果父類物件引用指向的實際是一個子類物件,那麼這個父類物件的引用可以用強制型別轉換(casting)成子類物件的引用
Person p1=new Person(“Liming”,50);
Person p2=new Student(“Zhangyi”,20, “THU”);
Student s2=(Student)p2;
Student s3=(Student)p;//編譯可以過,實際執行會出問題。
Person[ ] manypeople=new Person[100];
manypeople[0]=new Person(“Li”,18);
manypeople[1]=new Student(“Wang”,18, “PKU”);