???
雖然接觸Java已經(jīng)快一年了,也系統(tǒng)的學(xué)過(guò)Java語(yǔ)法,不過(guò)很多概念到現(xiàn)在都搞不清楚,現(xiàn)在決定重新把這些模糊的概念重新溫習(xí)一遍,今天就現(xiàn)總結(jié)一下抽象類(abstract class)。
1、使用abstract類的動(dòng)機(jī):可以參考 Cay?S.?Horstmann, Gary?Cornel 寫的書《Core Java? 2 Volume I - Fundamentals, Seventh Edition
》(順便羅嗦一下,該書是偶見(jiàn)過(guò)最好的Java入門書) “Classes, Superclasses, and Subclasses
”一節(jié),定義一個(gè)abstract class的格式是:修飾符(public, private, etc)+abstract+類名 或者 abstract + 修飾符 + 類名。
2、如果一個(gè)類至少存在一個(gè)抽象方法(abstract method),則它自身必須聲明成一個(gè)抽象類。但一個(gè)類可以被聲明成一個(gè)抽象類即使它沒(méi)有任何抽象方法。聲明一個(gè)abstract method的格式是:修飾符(public, private, etc)+abstract+返回類型 + 方法名 或者 abstract + 修飾符 + 返回類型 + 方法名。
3、一個(gè)抽象類可以有數(shù)據(jù)域和非抽象方法(concrete data and concrete methods)。
4、當(dāng)一個(gè)子類繼承某個(gè)抽象類時(shí),它可以有兩個(gè)選擇:
??? (1)??? 部分實(shí)現(xiàn)或完全不實(shí)現(xiàn)父類的所有抽象方法,但此時(shí)子類必須聲明為抽象類。
??? (2)??? 實(shí)現(xiàn)父類所有的抽象方法,此時(shí)之類不比聲明為抽象類。
5、抽象類不能被實(shí)例化(be instantiated),但可以實(shí)例化非抽象子類(concrete subclass)。
?? 可以聲明抽象類變量,但該變量必須指向一個(gè)非抽象子類.看下面一個(gè)例子:
???1.??Person?[]?people?=?new?Person[2];????
???2.?people[0]?=?new?Employee(
);????
???3.?people[1]?=?new?Student(
);??
???4.?for?(Person?p?:?people)??
???5.????System.out.println(p.getName()?+?","?+?p.getDescription());??
注意代碼中的一個(gè)調(diào)用:p.getDescription().可能有人會(huì)擔(dān)心這里調(diào)用了一個(gè)沒(méi)定義的方法。但是, 由于不能構(gòu)造抽象類Person的對(duì)象,所以p永遠(yuǎn)不會(huì)調(diào)動(dòng)Person對(duì)象,而是只會(huì)調(diào)用諸如Employee或Student這樣的具體子類方法。注意,如果沒(méi)有定義Person中抽象方法getDescription()但是通過(guò)p調(diào)用getDescription()則會(huì)產(chǎn)生編譯錯(cuò)誤,編譯器只允許調(diào)用在類中聲明的方法。
6、摘自《Core Java 2》的一個(gè)例子:

PersonTest.java
/**
???@version?1.01?2004-02-21
???@author?Cay?Horstmann
*/
import?java.text.*;
import?java.util.*;
public?class?PersonTest
{??
???public?static?void?main(String[]?args)
???{??
??????Person[]?people?=?new?Person[2];
??????//?fill?the?people?array?with?Student?and?Employee?objects
??????people[0]?=?new?Employee("Harry?Hacker",?50000,?1989,?10,?1);
??????people[1]?=?new?Student("Maria?Morris",?"computer?science");
??????//?print?out?names?and?descriptions?of?all?Person?objects
??????for?(Person?p?:?people)
?????????System.out.println(p.getName()?+?",?"?+?p.getDescription());
???}
}
abstract?class?Person
{??
???public?Person(String?n)
???{??
??????name?=?n;
???}
???public?abstract?String?getDescription();
???public?String?getName()
???{??
??????return?name;
???}
???private?String?name;
}
class?Employee?extends?Person
{??
???public?Employee(String?n,?double?s,
??????int?year,?int?month,?int?day)
???{??
??????super(n);
??????salary?=?s;
??????GregorianCalendar?calendar?=?new?GregorianCalendar(year,?month?-?1,?day);
??????hireDay?=?calendar.getTime();
???}
???public?double?getSalary()
???{??
??????return?salary;
???}
???public?Date?getHireDay()
???{??
??????return?hireDay;
???}
???public?String?getDescription()
???{??
??????return?String.format("an?employee?with?a?salary?of?$%.2f",?salary);
???}
???public?void?raiseSalary(double?byPercent)
???{??
??????double?raise?=?salary?*?byPercent?/?100;
??????salary?+=?raise;
???}
???private?double?salary;
???private?Date?hireDay;
}
class?Student?extends?Person
{??
???/**
??????@param?n?the?student's?name
??????@param?m?the?student's?major
???*/
???public?Student(String?n,?String?m)
???{??
??????//?pass?n?to?superclass?constructor
??????super(n);
??????major?=?m;
???}
???public?String?getDescription()
???{??
??????return?"a?student?majoring?in?"?+?major;
???}
???private?String?major;
}
參考資料:
Core Java 2 Volume I - Fundamentals, Seventh Edition
by Cay S. Horstman, Gary Cornell