在教程(十二)中,我們有這樣的假設。假設有這樣一個簡單需求(其實談 不上是需求,僅僅為了初學者容易理解而編造):某培訓中心要開發一個內部員 工管理系統。該培訓中心目前有兩個部門,技術資源部和業務部。技術資源部的 員工負責講課,稱為講師。業務部員工負責聯系洽談業務,稱為銷售。在管理系 統中,需要管理的是所有員工的姓名、薪水,以及講師的技術方向,銷售的任務 量。…..
基於這樣的假設,我們設計了三個類:父類Employee、子類Sales和Trainer 。如果我們有如下語句:
Employee e=new Employee();
是完全符合語法的。但是,我們從面向對象編程的角度出發,系統中存在的 對象,一定在現實中可以找到對應的實體。但是在現實中,是沒有Employee類的 對象的,只有Sales,或者Trainer。所以得出結論:Employee類不應該被實例化 。
如何保證一個類不被實例化哪?只要將這個類聲明為抽象類即可。使用 abstract關鍵字即可,如下:
public abstract class Employee { private String name; private double salary; //TBC }
Employee類聲明為抽象後,將不能實例化,如果出現如下語句:Employee e=new Employee();將會出現編譯錯誤。
但是抽象類依然可以作為類型使用,如:Employee e=new Sales();(後續文 章中將介紹該用法)。
初學者可以暫時把抽象類定義為:不能實例化的類,為抽象類。
接下來我們來考慮另外一個問題。
父類Employee中定義了一個方法:
public void setSalary(double salary,double rate) { this.salary = salary*(1+rate); }
但是如果子類Sales和Trainer雖然都需要實現這個業務邏輯,但是實現方式 卻都不相同,如Sales如下:
public void setSalary(double salary, double rate) { this.salary = salary*(1+2*rate); }
Trainer類的如下:
public void setSalary(double salary, double rate) { this.salary = salary*(1+0.5*rate); }
那麼,Employee類中的setSalary(double salary,double rate) 該如何處理?初學者往往會想,既然子類都不會使用父類的方法體,那麼就直接 取消該方法的聲明。這樣是不可行的,父類是子類共同特別的體現,子類中確實 都需要實現setSalary(double salary,double rate)這個邏輯,只是實現方式不 同而已。也就是說,我們需要一個方案,既能夠體現子類的共同特征,又不用寫 出沒用的方法體,這就是抽象方法。只要將父類的setSalary(double salary,double rate)方法聲明為如下即可:
public abstract void setSalary(double salary,double rate) ;
需要注意的是,抽象方法是沒有方法體的,聲明後直接使用;結束。
抽象方法和抽象類之間的關系是:
1) 抽象類中不一定有抽象方法
2) 有抽象方法的類一定是抽象類
因此,如果一個類繼承的父類中有抽象方法,那麼子類必須實現其抽象方法 ,否則子類也必須聲明為抽象類。
很多初學者會不太理解抽象類的作用,尤其抽象方法,覺得既然連實現邏輯 都沒有,又何必聲明?抽象類,抽象方法都是Java中非常重要的概念,抽象類是 多個子類共同特征的體現,抽象方法是子類共同行為的規范。