物件的繼承、介面這些知識就像線上遊戲剛創建帳號時,系統會自動帶著玩家完成一些事項和基礎技能點擊。換句話說,繼承、介面對於Coding Online的玩家是很基本、重要的。當然,物件的封裝、多型也是相當重要,但不在此討論,各位玩家務必要好好學習。
物件的繼承、介面這些知識就像線上遊戲剛創建帳號時,系統會自動帶著玩家完成一些事項和基礎技能點擊。換句話說,繼承、介面對於Coding Online的玩家是很基本、重要的。當然,物件的封裝、多型也是相當重要,但不在此討論,各位玩家務必要好好學習。
在談繼承、介面之前,先來看看最基本的物件與類別之間的關係,物件與類別的差異在哪,這應該有很多在新手村的玩家都沒有辦法回答。甚至,已經出了新手出的玩家也沒有辦法好好地回答。簡單的來說,
應該很多人看了還不懂差別在哪。舉個大師最常舉的例子,物件就好比房子而類別就是房子的設計圖。房子是根據設計圖建照出來的,設計圖上也會定義了許多房子的相關資訊,像是房子的大小、格局等等。再舉個例子,LEGO(樂高)的說明書與組合好的LEGO完成品,說明書就像是類別,在說明書裡會定義有哪些材料及個數。完成品就是照著說明書產出來的物件。
物件的繼承,可以讓子類別(繼承自的另一個類別的類別)擁有父類別(被繼承的類別)的屬性及方法。當然,子類別也可以重新定義父類別的屬性與方法。來看一個簡單的例子,一間公司裡面會有CEO、秘書、企劃人員、行銷人員..... 等等不同的職位。每種職位都會有一些特有資訊,所以可以將每種職位特有的資訊設計成一個類別,這裡以CEO與秘書來做範例。
/// <summary>
/// 秘書
/// </summary>
public class Secretary : Employee
{
public DateTime WrokingHours { get; set; }
/// <summary>
/// 職務加給
/// </summary>
public int Allowance { get; set; }
}
/// <summary>
/// 執行長
/// </summary>
public class CEO : Employee
{
/// <summary>
/// 秘書
/// </summary>
public List<Secretary> Secretaries { get; set; }
}
然而,不管是CEO或秘書都是公司的員工。所以,需要一個員工的類別,把不同職位的共通屬性放在這一個類別,再將職位類別繼承員工類別。如此一來,職位類別就能專注的存放該職位特定的屬性,將共通的屬性像是員工代碼、分機等資訊放到基底類別上。
/// <summary>
/// 員工
/// </summary>
public class Employee : Person
{
public string ID { get; set; }
public string Ext { get; set; }
}
再者,每一個員工都是人,所以會有一些姓名、性別等等的共通資訊。所以,員工又繼承了人這一個類別,將個人的資訊放置到基底類別中。
/// <summary>
/// 人
/// </summary>
public class Person
{
public string Name { get; set; }
public string Gender { get; set; }
public string Weight { get; set; }
public string Height { get; set; }
}
上述的例子中,職位繼承了員工,員工又繼承了人。所以在物件的世界裡,我們可以從職位物件取得員工代碼或是這一位員工的性別,皆是透過繼承關係而來。
介面
再談介面之前,先來講講另一件事。如果不是剛創建Coding online的玩家,應該會常常聽到「要依賴抽象類別,不要依賴具象類別」,如果這句話比喻成裝備,對於得到這個裝備的新手村玩家,打開背包的時候這一個裝備絕對是灰色的。因為物件導向的技能還沒點滿,所以這一句話跟天書一樣。
來試試用上述的例子來解釋這句話,我們都知道一間公司通常都會配一個以上的秘書給CEO,幫忙CEO管理日常行程,所以秘書一定要有管理CEO行事曆的能力。如果有訪談邀約或是公司會議直接詢問CEO是否有時間時,CEO通常會請對方轉洽秘書,讓祕書來管理。所以對於CEO而言,有邀約就是請秘書來管理,然後每天秘書在跟自己報告當天的行程即可。就算是秘書換人,CEO也不用管是誰,反正就是請對方找秘書就可以了。這個例子中,秘書就是一個抽象的代表,而真正在做秘書工作的人就是具象類別。CEO不用管每天的秘書是誰,有可能昨天的秘書是Ada,今天是Anna,明天是Christina,只要有需要就是請秘書來處理,反正不管是Ada, Anna還是Christina她們都是秘書,都會有管理行程的能力。
根據上面的敘述來更新程式碼,CEO的類別中,從依賴具象的秘書類別,變成秘書介面。原本的秘書類別也實作了秘書介面所需要的功能。
/// <summary>
/// 執行長
/// </summary>
public class CEO : Employee
{
/// <summary>
/// 秘書群
/// </summary>
public List<ISecretary> Secretaries { get; set; }
}
/// <summary>
/// 秘書介面
/// </summary>
public interface ISecretary
{
DateTime WorkingHours { get; set; }
/// <summary>
/// 職務加給
/// </summary>
int Allowance { get; set; }
/// <summary>
/// 登記會議
/// </summary>
void BookingMetting(Event meeting);
}
/// <summary>
/// 秘書
/// </summary>
public class Secretary : ISecretary, Employee
{
/// <summary>
/// 上班時間
/// </summary>
public DateTime WrokingHours { get; set; }
/// <summary>
/// 職務加給
/// </summary>
public int Allowance { get; set; }
/// <summary>
/// 登記會議.
/// </summary>
/// <param name="meeting">會議資訊</param>
public bool BookingMetting(Event meeting)
{
//// do something
}
}
這個例子中,我們讓祕書類別實作秘書介面。然而,一個類別是可以實作多個介面,秘書類別除了實作秘書介面也可以再實作其他介面。舉個例子來說,新增一個女朋友的類別,此類別也實作女朋友介面,提供一些方法。接著,可以讓女朋友類別也實作秘書介面,這樣女朋友類別也就可以當成秘書來使用了。換句話說,這樣概念就是讓女朋友來當自己的秘書。
public class GirlFriend : IGirlFriend, ISecretary
{
/// <summary>
/// 職務加給
/// </summary>
public int Allowance { get; set; }
/// <summary>
/// 工作時間
/// </summary>
public DateTime WorkingHours { get; set; }
/// <summary>
/// 暗黑技能A
/// </summary>
public void BlackFunctionA() { }
/// <summary>
/// 暗黑技能B
/// </summary>
public void BlackFunctionB() { }
/// <summary>
/// 登記時間
/// </summary>
public bool BookingMetting(Person person, Event meeting)
{
//// do something
return true;
}
}
當然可以讓祕書類別實作女朋友介面,如此一來,秘書也就有女朋友的暗黑技能了(筆者心聲: 當CEO真好.......)。不過,秘書實作女朋友介面與女朋友實作秘書介面,雖然在使用上是一模一樣的。但是,在實際上的意義可以相差許多。
/// <summary>
/// 秘書
/// </summary>
public class Secretary : Employee, ISecretary, IGirlFriend
{
public DateTime WrokingHours { get; set; }
/// <summary>
/// 職務加給
/// </summary>
public int Allowance { get; set; }
/// <summary>
/// 工作時間
/// </summary>
public DateTime WorkingHours { get; set; }
private Calendar _bossCalendar;
public bool BookingMetting(Person person, Event meeting)
{
throw new NotImplementedException();
}
public void BlackFunctionA()
{
//// do something
}
public void BlackFunctionB()
{
//// do something
}
}
當有人想要跟CEO約時間開會時,只需要跟其中一位秘書booking時間即可
var jack = new CEO();
var isBooking = jack.Secretaries.First().BookingMetting(
new Person()
{
Name = "Andy"
},
new Event()
{
Date = new DateTime(2015, 12, 25)
}
);
透過以上的例子,希望能夠讓大家了解「要依賴抽象類別,不要依賴具象類別」的原理,介面就是這一句話中抽象類別之一。當物件要使用另一個物件的功能時,盡可能的使用介面,而不適直接使用該物件。
在現實生活中還有許多這樣的案例,像是大家每天都在使用的USB,只要符合USB接頭的規格,不管你是什麼廠牌都是可以使用的。
免責聲明:
"文章一定有好壞,文章內容有對有錯,使用前應詳閱公開說明書"