文章目錄
如果自下而上在類的繼承層次結構中上移,位于上層的類更具有通用性,甚至可能更加抽象。從某種角度看, 祖先類更加通用, 隻是将它作為派生其他類的基類,而不作為想使用的特定的執行個體類。
抽象方法和抽象類必須使用 abstract 修飾符來定義,有抽象方法的類隻能被定義成抽象類,抽象類裡可以沒有抽象方法 。
抽象方法和抽象類的規則如下 。
- 抽象類必須使用 abstract 修飾符來修飾,抽象方法也必須使用 abstract 修飾符來修飾,抽象方法不能有方法體。
- 抽象類不能被執行個體化,無法使用 new 關鍵字來調用抽象類的構造器建立抽象類的執行個體 。 即使抽象類裡不包含抽象方法,這個抽象類也不能建立執行個體。
- 抽象類可以包含成員變量、方法(普通方法和抽象方法都可以)、構造器、初始化塊、内部類(接口、枚舉) 5 種成分 。 抽象類的構造器不能用于建立執行個體, 主要是用于被其子類調用。
- 含有抽象方法的類(包括直接定義了 一個抽象方法;或繼承了 一個抽象父類,但沒有完全實作父類包含的抽象方法;或實作了一個接口,但沒有完全實作接口包含的抽象方法三種情況)隻能被定義成抽象類 。
抽象類執行個體
public class Main {
public static void main(String[] args) {
Person p = new Student();
p.run();
}
}
//抽象類Person
abstract class Person {
//抽象類
public abstract void run();
}
//抽象類子類
class Student extends Person {
//抽象類子類必須實作父類抽象方法
@Override
public void run() {
System.out.println("Student.run");
}
}
抽象類不能建立執行個體,隻能當成父類來被繼承。
從語義的角度來看,抽象類是從多個具體類中抽象出來的父類,它具有更高層次的抽象。從多個具有相同特征的類中抽象出一個抽象類,以這個抽象類作為其子類的模闆,進而避免了子類設計的随意性。抽象類展現的就是一種模闆模式的設計,抽象類作為多個子類的通用模闆,子類在抽象類的基礎上進行擴充、改造,但子類總體上會大緻保留抽象類的行為方式。
如果編寫一個抽象父類,父類提供了多個子類的通用方法,并把一個或多個方法留給其子類實作,這就是一種模闆模式,模闆模式也是十分常見且簡單的設計模式之一 。
下面再是一個個模闆模式的範例,在這個範例的抽象父類中,父類的普通方法依賴于一個抽象方法,而抽象方法則推遲到子類中提供實作 。
模闆模式範例-抽象父類
public abstract class SpeedMeter{
// 轉速
private double turnRate;
public SpeedMeter() {}
// 把計算車輪周長的方法定義成抽象方法
public abstract double calGirth() ;
public void setTurnRate(double turnRate){
this.turnRate = turnRate ;
}
//定義計算速度的通用算法
public double getSpeed(){
// 速度等于周長*轉速
return calGirth () * turnRate;
}
}
模闆模式範例-子類
public class CarSpeedMeter extends SpeedMeter{
private double radius;
public CarSpeedMeter(double radius){
this.radius = radius ;
}
//實作父類抽象方法
public double calGirth(){
return radius * 2 * Math.PI ;
}
public static void main(String[] args){
//既可建立CarSpeedMeter 類的對象,也可通過該對象來取得目前速度
CarSpeedMeter csm = new CarSpeedMeter(O.34) ;
csm.setTurnRate(15) ;
System.out.println(csm . getSpeed()) ;
}
}
SpeedMeter 類裡提供了速度表的通用算法 , 但一些具體的實作細節則推遲到其子類 CarSpeedMeter類中實作 。 這也是一種典型的模闆模式。
模闆模式在面向對象的軟體中很常用,其原理簡單,實作也很簡單 。 下面是使用模闆模式的一些簡單規則 。
- 抽象父類可以隻定義需要使用的某些方法,把不能實作的部分抽象成抽象方法,留給其子類去實作 。
- 父類中可能包含需要調用其他系列方法的方法,這些被調方法既可以由父類實作,也可以由其子類實作 。 父類裡提供的方法隻是定義了 一個通用方法,其實作也許并不完全由自身實作,而必須依賴于其子類的輔助 。
當使用了抽象的思想後:調用者隻需關心抽象方法的定義,不必關心子類的具體實作。
參考:
【1】:《瘋狂Java講義》
【2】:《Java核心技術 卷一》
【3】:
https://www.liaoxuefeng.com/wiki/1252599548343744/1260456371027744