Java程式用抽象類別(abstract class)來實作自然界的抽象概念。抽象類別的作用在於將許多有關的類別組織在一起,提供一個公共的類,即抽象類,而那些被它組織在一起的具體的類別將作為它的子類別由它派生出來。抽象類別刻畫了公有行為的特徵,並透過繼承機制傳送給它的衍生類別。在抽象類別中定義的方法稱為抽象方法,這些方法只有方法頭的聲明,而用一個分號來取代方法體的定義,即只定義成員方法的介面形式,而沒有具體操作。只有衍生類別對抽象成員方法的重定義才真正實現與該衍生類別相關的操作。
在各子類別繼承了父類別的抽象方法之後,再分別用不同的語句和方法體來重新定義它,形成若干個名字相同,返回值相同,參數列表也相同,目的一致但是具體實現有一定差別的方法。抽象類別中定義抽象方法的目的是實現一個接口,即所有的子類別對外都呈現一個相同名字的方法。抽象類別是它的所有子類別的公共屬性的集合,是包含一個或多個抽象方法的類別。使用抽象類別的一大優點就是可以充分利用這些公共屬性來提高開發和維護程序的效率。對於抽象類別與抽象方法的限制如下:
(1)凡是用abstract 修飾符修飾的類別稱為抽象類別。凡是用abstract修飾符修飾的成員方法稱為抽象方法。
(2)抽象類別中可以有零個或多個抽象方法,也可以包含非抽象的方法。
(3)抽象類別中可以沒有抽象方法,但是,有抽象方法的類別必須是抽象類別。
(4)對於抽象方法來說,在抽象類別中只指定其方法名稱及其類型,而不書寫其實作程式碼。
(5)抽象類別可以衍生子類,在抽象類別衍生的子類別中必須實作抽象類別中定義的所有抽象方法。
(6)抽象類別不能創建對象,創建對象的工作由抽象類別派生的子類別來實現。
(7)如果父類別中已有同名的abstract方法,則子類別中就不能再有同名的抽象方法。
(8)abstract不能與final並列修飾同一個類別。
(9)abstract 不能與private、static、final或native並列修飾同一個方法。
Java語言規定,當一個類別裡面有抽象方法的時候,這個類別必須宣告為抽象類別。
子類別繼承父類別時,如果這個父類別裡面有抽象方法,而子類別覺得可以去實作父類別的所有抽象方法,那麼子類別必須去實作父類別的所有抽象方法,如:
/** * 子類別Dog繼承抽象類別Animal,並且實作了抽象方法enjoy * @author gacl * */class Dog extends Animal { /** * Dog類別加入自己特有的屬性*/ public String furColor; public Dog( String n, String c) { super(n);//呼叫父類別Animal的建構方法this.furColor = c; } @Override public void enjoy() { System.out.println("狗叫聲...."); }}
這個父類別裡面的抽象方法,子類別如果覺得實作不了,那麼把就子類別也宣告成一個抽象類別,如:
/** * 這裡的子類別Cat從抽象類別Animal繼承下來,自然也繼承了Animal類別裡面宣告的抽象方法enjoy(), * 但子類別Cat覺得自己去實作這個enjoy()方法也不合適,因此它把它自己也宣告成一個抽象的類, * 那麼,誰去實作這個抽象的enjoy方法,誰繼承了子類,那誰就去實作這個抽象方法enjoy()。 * @author gacl * */abstract class Cat extends Animal { /** * Cat加入自己獨特的屬性*/ public String eyeColor; public Cat(String n, String c) { super(n);//呼叫父類別Animal的建構法this.eyeColor = c; }}
這裡的子類別Cat從抽象類別Animal繼承下來,自然也繼承了Animal類別裡面宣告的抽象方法enjoy(),但子類別Cat覺得自己去實作這個enjoy()方法也不合適,因此它把它自己也宣告成一個抽象的類,那麼,誰去實作這個抽象的enjoy方法,誰繼承了子類,那誰就去實作這個抽象方法enjoy()。如:
/** * 子類別BlueCat繼承抽象類別Cat,實作了從父類別Cat繼承下來的抽象方法enjoy * @author gacl * */class BlueCat extends Cat { public BlueCat(String n, String c) { super(n , c); } /** * 實作了抽象方法enjoy */ @Override public void enjoy() { System.out.println("藍貓叫聲..."); } }
完整的測試程式碼如下:
package javastudy.summary;/** * 父類Animal * 在class的前面加上abstract,也就是宣告成這樣:abstract class Animal * 這樣Animal類別就成了一個抽象類別了*/abstract class Animal { public String name; public Animal(String name) { this.name = name; } /** * 抽象方法* 這裡只有方法的定義,沒有方法的實作。 */ public abstract void enjoy(); }/** * 這裡的子類別Cat從抽象類別Animal繼承下來,自然也繼承了Animal類別裡面宣告的抽象方法enjoy(), * 但子類別Cat覺得自己去實現這個enjoy()方法也不合適,因此它把它自己也宣告成一個抽象的類, *那麼,誰去實作這個抽象的enjoy方法,誰繼承了子類,那誰就去實作這個抽象方法enjoy()。 * @author gacl * */abstract class Cat extends Animal { /** * Cat加入自己獨特的屬性*/ public String eyeColor; public Cat(String n, String c) { super(n);//呼叫父類別Animal的建構方法this.eyeColor = c; }}/** *子類別BlueCat繼承抽象類別Cat,並且實作了從父類別Cat繼承下來的抽象方法enjoy * @author gacl * */class BlueCat extends Cat { public BlueCat(String n, String c) { super(n, c); } /** * 實作了抽象方法enjoy */ @Override public void enjoy() { System.out.println("藍貓叫..."); } }/** * 子類別Dog繼承抽象類別Animal,並且實作了抽象方法enjoy * @author gacl * */class Dog extends Animal { /** * Dog類別加入自己特有的屬性*/ public String furColor; public Dog (String n, String c) { super(n);//呼叫父類別Animal的建構方法this.furColor = c; } @Override public void enjoy() { System.out.println("狗叫聲...."); }}public class TestAbstract { /** * @param args */ public static void main(String[] args) { /** *把Cat類別宣告成一個抽象類別以後,就不能再對Cat類別進行實例化了, * 因為抽象類別是殘缺不全的,缺手臂少腿的,因此抽象類別不能被實例化。 */ //Cat c = new Cat("Catname","blue"); Dog d = new Dog("dogname","black"); d.enjoy();//呼叫自己實作了的enjoy方法BlueCat c = new BlueCat("BlueCatname","blue"); c.enjoy();//呼叫自己實作了的enjoy方法}}