Window窗體可以用抽象類來設計,可以把公有操作和屬性放到一個抽象類裡,讓窗體和對話框繼承自這個抽象類,再根據自己的需求進行擴展和完善。
打印操作可以作為一個接口提供給每個需要此功能的窗體,因為窗體的內容不同,就要根據他們自己的要求去實現自己的打印功能。打印時只通過接口來調用,而不用在乎是那個窗體要打印。
有的書上寫到C#推薦使用接口(Interface)來替代抽象基類(Abstract Class),並強調使用接口的諸多好處,這點我不敢苟同,從上面列表中看來,兩者之間還是存在不少差異的,而這種差異的存在性必然決定了適用場景的不同,例如在抽象基類中可以為部分方法提供默認的實現,從而避免在子類中重復實現它們,提高代碼的可重用性,這是抽象類的優勢所在;而接口中只能包含抽象方法。至於何時使用抽象基類何時使用接口關鍵還是取決於用戶是如何看待繼承類之間的聯系的,用戶更加關心的是它們之間的個性差異還是它們之間的共性聯系。舉個生活中的例子加以說明。
如果給你三個對象分別是人、魚、青蛙,讓你為他們設計個基類來概括它們之間的聯系,那麼首先給你的感覺肯定是它們個體間的差異性較大,很難抽象出共性,然而若讓你概括他們行為之間的共性,你可能想了想會意識到他們都會游泳,只不過是游泳方式迥異。那麼這時你就應當考慮使用接口而不是抽象基類,原因有三條:
interface ISwim
{
void Swim();
}
public class Person : ISwim
{
public void Swim()
{
//Swimming in person's style.
}
}
public class Frog : ISwim
{
public void Swim()
{
//Swimming in frog's style.
}
}
public class Fish : ISwim
{
public void Swim()
{
//Swimming in fish's style.
}
}
這時再給你三個對象,分別是鲫魚、鯉魚、金魚,仍然讓你設計基類來概括它們之間的聯系,那麼你第一個意識到的肯定是它們都屬於魚類,其次是他們游泳的方式可能稍有差異,這時就應當使用抽象基類而不是接口,對比著上面的例子,原因也有三條:
abstract public class Fish
{
abstract public void Swim();
}
public class 鲫魚 : Fish
{
public override void Swim()
{
//Swim like a 鲫魚
}
}
public class 鯉魚 : Fish
{
public override void Swim()
{
//Swim like a 鯉魚
}
}
public class 金魚 : Fish
{
public override void Swim()
{
//Swim like a 金魚
}
}
觀察在使用接口或是使用抽象基類的幾條理由中,第三條理由其實是一樣的,它所描述的是面向對象中多態的概念,即通過覆蓋父類的方法來實現,在運行時根據傳遞的對象引用,來調用相應的方法。第二條理由開始產生分歧,接口更加強調了繼承對象間具有相同的行為,而抽象類同時還強調了繼承對象間具有相同的屬性。而真正將接口與抽象基類區分開的則是理由歸納如下:
通過相同與不同的比較,我們只能說接口和抽象類,各有所長,但無優略。在實際的編程實踐中,我們要視具體情況來酌情量才,但是以下的經驗和積累,或許能給大家一些啟示,除了我的一些積累之外,很多都來源於經典,我相信經得起考驗。所以在規則與場合中,我們學習這些經典,最重要的是學以致用,當然我將以一家之言博大家之笑,看官請繼續。
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/fxh_hua/archive/2009/08/20/4464739.aspx