【Java】繼承、抽象、組合
類的繼承
類的繼承
一種由已有的類建立新類的機制,是物件導向程式設計的基石之一。通過繼承,可以根據已有類來定義新類,新類擁有已有類的所有功能。
Java只支援類的單繼承,每個子類只能有一個直接父類
父類是所有子類的公共屬性及方法的集合,子類則是父類的特殊化
繼承機制可以提高程式的抽象程度,提高程式碼的可重用性
基類和派生類
-
基類(base class)
也稱超類(superclass)是被直接或間接繼承的類 -
派生類(derived-class)
也稱子類 (subclass)繼承其他類而得到的類
繼承所有祖先的狀態和行為
派生類可以增加變數和方法
派生類也可以覆蓋(override)繼承的方法
子類物件與父類物件存在“IS A”(或“is a kind of”)的關係
派生類產生的物件從外部來看,它應該包括
- 與基類相同的介面
- 可以具有更多的方法和資料成員
其內包含著一個基類型別的子物件
繼承語法:
class childClass extends parentClass
{
//類體
}
舉個例子,在一個公司中,有普通員工(Employees)及管理人員(Magagers)兩類人員
職員物件(Employees)可能有的屬性資訊包括
員工號(employeeNumber)
姓名(name)
地址(address)
電話號碼(phoneNumber)
管理人員(Managers)除具有普通員工的屬性外,還可能具有下面的屬性
職責(responsibilities)
所管理的職員(listOfEmployees)
//父類Employee
class Employee
{
int employeeNumbe ;
String name, address, phoneNumber ;
}
//子類Manager
class Manager extends Employee
{
//子類增加的資料成員
String responsibilities, listOfEmployees;
}
需要注意的:
子類不能直接訪問從父類中繼承的私有屬性及方法,但可使用公有(及保護)方法進行訪問
public class B {
public int a = 10;
private int b = 20;
protected int c = 30;
public int getB() { return b; }
}
public class A extends B {
public int d;
public void tryVariables() {
System.out.println(a); //允許
System.out.println(b); //不允許
System.out.println(getB()); //允許
System.out.println(c); //允許
}
}
隱藏和覆蓋
子類對從父類繼承來的屬性變數及方法可以重新定義
屬性的隱藏
class Parent {
Number aNumber;
}
class Child extends Parent {
Float aNumber;
}
- 子類中宣告瞭與父類中相同的成員變數名,則從父類繼承的變數將被隱藏
- 子類擁有了兩個相同名字的變數,一個繼承自父類,另一個由自己宣告
- 當子類執行繼承自父類的操作時,處理的是繼承自父類的變數;而當子類執行它自己宣告的方法時,所操作的就是它自己宣告的變數
訪問被隱藏的父類屬性
- 呼叫從父類繼承的方法,則操作的是從父類繼承的屬性
- 使用super.屬性
class A1
{ int x = 2;
public void setx(int i)
{ x = i; }
void printa()
{System.out.println(x);}
}
class B1 extends A1
{ int x=100;
void printb()
{ super.x = super.x +10 ;
System.out.println("super.x=" + super.x + " x= " + x);
}
}
public class Exam4_4Test
{ public static void main(String[] args)
{ A1 a1 = new A1();
a1.setx(4);
a1.printa();
B1 b1 = new B1();
b1.printb();
b1.printa();
b1.setx(6); // 將繼承x值設定為6
b1.printb();
b1.printa();
a1.printa();
}
}
執行結果:
4
super.x= 12 x= 100
12
super.x= 16 x= 100
16
4
操作父類靜態屬性舉例
子類不能繼承父類中的靜態屬性,但可以對父類中的靜態屬性進行操作。如在上面的例子中,將“int x = 2;”改為“static int x = 2;”,再編譯及執行程式,會得到下面的結果
4 super.x= 14 x= 100 14 super.x= 16 x= 100 16 16
在上面的結果中,第一行及最後一行都是語句“a1.printa();”輸出的結果,顯然類B中的printb()方法修改的是類A中的靜態屬性x
方法覆蓋
如果子類不需使用從父類繼承來的方法的功能,則可以宣告自己的同名方法,稱為方法覆蓋
覆蓋方法的返回型別,方法名稱,引數的個數及型別必須和被覆蓋的方法一模一樣
只需在方法名前面使用不同的類名或不同類的物件名即可區分覆蓋方法和被覆蓋方法
覆蓋方法的訪問許可權可以比被覆蓋的寬鬆,但是不能更為嚴格
方法覆蓋的應用場合
- 子類中實現與父類相同的功能,但採用不同的演算法或公式
- 在名字相同的方法中,要做比父類更多的事情
- 在子類中需要取消從父類繼承的方法
注意事項
必須覆蓋的方法
派生類必須覆蓋基類中的抽象的方法,否則派生類自身也成為抽象類.
不能覆蓋的方法
基類中宣告為final的終結方法
基類中宣告為static 的靜態方法
呼叫被覆蓋的方法
super.overriddenMethodName();
Object類
終結類與終結方法
抽象類
泛型
類的組合
包的應用
本章小結
相關文章
- Java中的繼承與組合Java繼承
- java抽象繼承-模板方法Java抽象繼承
- 繼承與組合繼承
- prefer 組合 to 繼承繼承
- Java之繼承和抽象類Java繼承抽象
- JAVA介面繼承、抽象類等Java繼承抽象
- 組合優於繼承繼承
- 深入理解java中的組合和繼承Java繼承
- js 組合繼承詳解JS繼承
- JavaScript中的繼承和組合JavaScript繼承
- 菜鳥譯文(一)——Java中的繼承和組合Java繼承
- PHP 抽象類繼承抽象類時的注意點PHP 抽象類繼承抽象類時的注意點PHP抽象繼承
- Docker的組合優於繼承 - frankelDocker繼承
- 類的組合與繼承——作業繼承
- YTU-OJ-繼承與組合繼承
- 繼承、抽象個人小結繼承抽象
- 繼承+多型+抽象類繼承多型抽象
- Java基礎10 介面的繼承與抽象類Java繼承抽象
- 【設計模式】如何用組合替代繼承設計模式繼承
- javascript組合繼承的基本原理JavaScript繼承
- c# abstract抽象類及抽象方法_繼承C#抽象繼承
- 繼承 重寫和抽象類繼承抽象
- JAVA類的頂層Type抽象和繼承關係Java抽象繼承
- PHP 抽象類繼承抽象類時的注意點PHP抽象繼承
- python物件導向的繼承-組合-02Python物件繼承
- 組合思維與繼承思維的不同繼承
- 類的組合、繼承、模板類、標準庫繼承
- Java繼承Java繼承
- C# OOP:繼承,介面和抽象類C#OOP繼承抽象
- 【JAVA】筆記(5)--- final;抽象方法;抽象類;介面;解析繼承,關聯,與實現;Java筆記抽象繼承
- java繼承extendsJava繼承
- Java的繼承Java繼承
- Java單繼承Java繼承
- java中繼承Java中繼繼承
- JAVA 之 繼承Java繼承
- java 的 四 個 基 本 特 性 ——封裝 繼承 多型 抽象Java封裝繼承多型抽象
- Java抽象類、繼承及多型和介面卡的實現Java抽象繼承多型
- JAVA學習線路:day01物件導向(繼承、抽象類)Java物件繼承抽象