Java開發筆記(五十七)因抽象方法而產生的抽象類

前面介紹了類的常見用法,使人感嘆面向對象的強大,幾乎平常生活中的全部事物,均可以抽象成Java的基類及其子類。然而抽象操做也有反作用,就是某個抽象而來的行爲多是不肯定的,好比半夜雞叫,若是是公雞則一定「喔喔喔」地叫,若是是母雞則一定「咯咯咯」地叫,可要是不能肯定這隻雞是公雞仍是母雞抑或小雞,系統怎麼知道它會怎麼叫?落實到雞類Chicken的定義代碼中,它的call方法便沒法給出具體的叫聲了,儘管雞類可以派生出公雞類和母雞類,再在公雞類和母雞類重寫call方法,可是外部仍然能夠建立雞類的實例,接着調用雞類實例的call方法,此時該指望這隻雞發出什麼叫聲呢?不論是讓雞類胡言亂語、語無倫次,仍是讓雞類默不做聲、噤若寒蟬,顯然都與真實狀況有很大出入。
因而可知,某些類其實並不能拿來直接使用,充其量只能算半成品,必須通過進一步的加工,造成最終的成品方能給外部調用。鑑於前述的雞類存在叫喚這個不肯定的方法,故而理應將它納入半成品之列;至於由雞類派生而來的公雞類與母雞類,由於包括叫喚在內的每一個方法都是明確的,因此它們才成爲機能鑑權的完整類。在Java編程中,功能不肯定的方法被稱做抽象方法,而包含抽象方法的類受到牽連就變成了抽象類。在類的定義代碼裏面,經過關鍵字abstract來標識抽象方法及抽象類;凡是被abstract修飾的抽象方法,因爲方法的具體實現並不明確,所以抽象方法沒有花括號所包裹着的方法體;凡是被abstract修飾的抽象類,因爲包含了至少一個抽象方法,所以不容許外部建立抽象類的實例,不然就會出現雞類實例不知如何叫喚的尷尬。除此以外,抽象類還有下列兩點須要注意:
一、abstract只能用來修飾抽象方法和抽象類,不可用於修飾成員屬性,由於屬性值自己就容許經過賦值來改變,無所謂抽象不抽象。
二、雖然抽象類依舊能夠擁有構造方法,但它的構造方法並不能被外部直接調用,由於外部不容許經過構造方法來建立抽象類的實例,抽象類的構造方法只能提供給它的子類調用。
絮絮不休了這麼多抽象概念,接着嘗試把以前的雞類改寫成抽象類,修改後的抽象雞類定義代碼示例以下:html

//演示抽象類的定義
abstract public class Chicken {

	// 定義一個名稱屬性
	public String name;
	// 定義一個性別屬性
	public int sex;
	
	// 定義一個抽象的叫喚方法。注意後面沒有花括號,而且以分號結尾
	abstract public void call();

	// 即便抽象類定義了構造方法,外部也沒法建立它的實例
	public Chicken() {
	}

	// Java只有抽象類和抽象方法,沒有抽象屬性的說法
	//abstract public String cry;
}

而後分別編寫繼承自雞類的公雞類和母雞類,其中雞類的抽象方法call是必須在子類中重寫的,只有這樣,派生而來的子類才具有全部完善的行爲動做;不然的話,這個子類仍舊是個還沒有完工的半成品,依然屬於抽象類的行列。下面是重寫了call方法的公雞類代碼例子:java

//定義一個繼承自抽象雞類的公雞類
public class Cock extends Chicken {
	
	public Cock() {
		// 公雞的性別固定爲雄性
		sex = 0;
	}

	// 重寫了公雞的叫喚方法。若是不重寫父類的抽象方法,那麼該子類仍舊爲抽象類
	public void call() {
		System.out.println("喔喔喔");
	}
}

一樣重寫了call方法的母雞類代碼以下所示:編程

//定義一個繼承自抽象雞類的母雞類
public class Hen extends Chicken {
	
	public Hen() {
		// 母雞的性別固定爲雌性
		sex = 1;
	}

	// 重寫了母雞的叫喚方法。若是不重寫父類的抽象方法,那麼該子類仍舊爲抽象類
	public void call() {
		System.out.println("咯咯咯");
	}
}

最後輪到外部調用各類雞類了,對於外部而言,惟一的區別是外部不能建立抽象類的實例,其它子類的調用則跟從前同樣沒有變化。具體的外部調用代碼見下:日誌

		// 不能建立抽象類的實例,由於抽象類是個還沒有完工的類
		//Chicken chicken  = new Chicken();
		// 建立一個公雞實例,公雞類繼承自抽象類Chicken
		Cock cock = new Cock();
		cock.call(); // 調用公雞實例的叫喚方法
		// 建立一個母雞實例,母雞類繼承自抽象類Chicken
		Hen hen = new Hen();
		hen.call(); // 調用母雞實例的叫喚方法

 

運行上面的調用代碼,獲得如下的日誌結果,可見子類重寫後的call方法正常工做。htm

喔喔喔
咯咯咯

  

更多Java技術文章參見《Java開發筆記(序)章節目錄對象

相關文章
相關標籤/搜索