Java開發筆記(四十八)類的簡單繼承

pinlantu發表於2019-01-13

前面介紹了類的基本用法,主要是如何封裝一個類的各項要素,包括成員屬性、成員方法、構造方法等,想必大家對類的簡單運用早已駕輕就熟。所謂“物以類聚,人以群分”,之所以某些事物會聚在一起,乃是因為它們擁有類似的品性。那麼物件導向的目的,就是將一群事物之間共同的行為特徵提煉出來,從而歸納為具有普適性的型別。像日常生活中說的昆蟲、魚類、鳥類,便是人們把外表相似、習性相近的一系列動物歸類的結果。
以鳥類為例,按照科學家的定義,它們是動物界→脊索動物門→鳥綱下面所有動物的總稱。倘若按照大眾的觀點,鳥類為長著一對翅膀和兩條腿的有羽動物的統稱,特別是羽毛把鳥類與各種昆蟲以及蝙蝠區別開來。假設現在有一群鳥類,需要通過幾項特徵將它們區分開,則可提問幾個為什麼,諸如它的名稱是什麼、它的叫聲是什麼、它的性別是什麼等等。這些用來區別鳥兒個體的特徵,對應於物件導向理論的屬性概念,那麼在Java程式設計之中,可以設計一個名叫Bird的鳥類,並給Bird類定義名稱、叫聲、性別等成員屬性,以及讀寫屬性的成員方法,如此便構成了程式世界裡面的鳥類定義。
至於Bird類的具體定義,相信大家參照之前的類封裝,即可輕車熟路填寫其中的成員屬性、成員方法,乃至構造方法等要素。下面是一個Bird類的詳細定義程式碼例子:

public class Bird {
	// 定義鳥的名稱
	private String name;
	// 定義鳥的叫聲
	private String voice;
	// 定義鳥的性別型別。0表示雄性,1表示雌性
	private int sexType;
	// 定義鳥的性別名稱
	private String sexName;
	
	// 鳥類的構造方法(無任何輸入引數)
	public Bird() {
		this.name = "鳥";
	}

	// 鳥類的構造方法(輸入引數包含:名稱、性別、叫聲)
	public Bird(String name, int sexType, String voice) {
		this.name = name;
		this.voice = voice;
		setSexType(sexType); // 該方法內部同時修改性別型別和性別名稱
	}
	
	// 設定鳥的名稱
	public void setName(String name) {
		this.name = name;
	}

	// 獲取鳥的名稱
	public String getName() {
		return this.name;
	}

	// 設定鳥的叫聲
	public void setVoice(String voice) {
		this.voice = voice;
	}

	// 獲取鳥的叫聲
	public String getVoice() {
		return this.voice;
	}

	// 設定鳥的性別型別,並自動調整性別名稱
	public void setSexType(int sexType) {
		this.sexType = sexType;
		this.sexName = (sexType==0) ? "雄" : "雌";
	}

	// 獲取鳥的性別型別
	public int getSexType() {
		return this.sexType;
	}

	// 獲取鳥的性別名稱
	public String getSexName() {
		return this.sexName;
	}

	// 輸出鳥類的基本資訊描述文字
	public String toString() {
		String desc = String.format("這是一隻%s%s,它會%3$s、%3$s地叫。", 
				this.sexName, this.name, this.voice);
		return desc;
	}
}

有了上面的鳥類定義,然後外部才能按部就班地使用Bird類,譬如通過Bird宣告一隻鴿子的例項,則相關的呼叫程式碼如下所示:

		// 建立一個鳥類的例項
		Bird pigeon = new Bird();
		pigeon.setName("鴿子");
		pigeon.setSexType(1);
		pigeon.setVoice("咕咕");
		System.out.println(pigeon.toString());

 

執行以上的程式碼例子,可觀察到以下的日誌輸出結果:

這是一隻雌鴿子,它會咕咕、咕咕地叫。

 

可是鴿子並非單獨的一種鳥類,而是鳥綱→鴿形目→鳩鴿科→鴿屬下面所有鴿類的統稱,包括家鴿、巖鴿、銀鴿、雪鴿、斑鴿、黃腿鴿、白頭鴿等等,這些鴿類動物相互之間具備更接近的習性特徵,理應擁有自己的類定義如Pigeon類。
考慮到所有的鳥類動物都存在大類之下再分小類的需求,小類在大類的基礎上再體現本類的特色屬性,故而定義小類之時不必另起爐灶,完全可以基於大類然後修修補補形成新的小類定義。這種小類基於大類的關係,在物件導向體系中被稱作“繼承”,意思是小類繼承了大類的所有成員,大類更專業的稱呼叫“基類”,基於大類的小類也被起了個大名叫做“派生類”。
現在就以前述的Bird為基類,給它擴充套件出一個新的派生類Swallow(燕子類),準備把鳥綱→雀形目→燕科下面的家燕、雨燕、金絲燕等包羅在內。Java程式碼中表示繼承關係的關鍵字是extends,從A類派生出B類的寫法為“class B extends A”,其餘的類定義框架保持不變。於是從Bird派生而來的Swallow類定義程式碼示例如下:

//定義了一個繼承自鳥類的燕子類
public class Swallow extends Bird {
	// 燕子類未重寫任何構造方法,則預設使用不帶輸入引數的構造方法
}

 

僅僅看Swallow類的程式碼定義,發現內部空空如也,其實它早已繼承了Bird類的所有成員屬性和成員方法,以及預設的構造方法。外部使用Swallow類的時候,就像操作Bird類一樣的用法,比如下面程式碼演示瞭如何建立燕子類的例項、以及如何呼叫該例項的方法:

		// Swallow類使用不帶任何引數的預設構造方法
		Swallow swallow = new Swallow();
		swallow.setName("燕子");
		swallow.setSexType(0);
		swallow.setVoice("啾啾");
		System.out.println(swallow.toString());

 

執行上面的演示程式碼,可以看到下述的日誌資訊:

這是一隻雄燕子,它會啾啾、啾啾地叫。

 

由此可見Swallow類的確完整繼承了Bird類的所有成員。

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

相關文章