本文的英文標題為「distinguish between implementing inte***ces and overriding virtual functions」,但是文章的內容主要涉及的是如何在多層繼承中使用介面,因此覺得文章標題和內容有些不符(也許我水平比較低,無法真正理解文章的內容)。
眾所周知,在乙個類中對介面所定義方法的實現,預設是不會加上「virtual」關鍵字的。
一般的形式如下。
inte***ce imsg
public
class myclass:imsg
#endregion
} 因此,那麼如果乙個型別繼承了實現介面的型別,預設的情況下是無法過載介面所定義的方法。不過在子類中雖說可以用「
new」關鍵字覆蓋父類的方法,但是這並不能代替介面所定義的方法,例如:
public
class myderivedclass:myclass
} //only for test
myderivedclass d = new myderivedclass();
d.message();// prints
「myderivedclass」
imsg m = d as imsg;
m.message();// prints
「myclass」
很明顯,這樣的寫法並不能達到我們真正想要的目的。那麼如何在多層繼承中,能使介面實現區域性化,簡單說,就是在不同的型別中有不同的實現方法。一般來說,需要在原有的基礎上進行轉化,通常有四種解決方法。
第一種方法,在子類中增加介面標識,這樣就可以名正言順實現介面定義的方法。例如如上的改寫。
public
class myderivedclass:myclass, imsg
} 那麼如上改寫,對於前一部分測試**來說,執行正確;但是這樣的實現會存在潛在的
bug,例如:
//only for test
myderivedclass d = new myderivedclass();
d.message();//print "myderivedclass"
imsg m = d as imsg;
m.message();//print "myderivedclass"
myclass b = d;
b.message();//print "myclass"
也就是說,這樣方法可以解決介面在多層繼承中的問題,但是處理得不完美。相對於這種方法,另外三種方法要好很多,但是這三種方法都牽扯到虛函式。
首先介紹的,也是最簡單的,就是在實現的時候,給介面定義的函式增加「
virtual」標識。例如:
public
class myclass:imsg
#endregion
} public
class myderivedclass:myclass
} 不過,我覺得這個方法有些投機,或者從某種意義上說,已經變更了介面定義。
那麼接下來介紹的,就是用抽象類進行重新封裝。例如:
public
abstract
class myclass:imsg
這種方法相對前面的一種方法來說,是比較正規的,但是給人一種多此一舉的感覺,除非為了後期能提供
imsg介面轉換,否則直接用如下的方式會更好。
public
abstract
class myclass
最後一種實現,也是我比較喜歡的一種,類似於以前文章中提到的
idisposable實現方法,那麼對於這個例子,可以如下改寫。
public
class myclass:imsg
#endregion
protected
virtual
void showmessage()
} public
class myderivedclass:myclass
} 這樣的改寫,既保留介面的完整性,同時**比較直觀,介面實現是介面實現,虛函式過載是虛函式過載,兩者是分離的。不過相對於前兩個虛函式實現方法,這乙個方法需要編寫的**要相對多一些,效率略低(因為呼叫介面方法需要呼叫兩個函式)。
介面只是宣告方法和屬性,方法的一些標識並沒有特殊限制,因此在實現的時候可以增加一些標識,除了「virtual」外,還有「abstract」和「sealed」。
區分介面實現與虛函式過載
眾所周知,在乙個類中對介面所定義方法的實現,預設是不會加上 virtual 關鍵字的。一般的形式如下。inte ce imsg public class myclass imsg endregion 因此,那麼如果乙個型別繼承了實現介面的型別,預設的情況下是無法過載介面所定義的方法。不過在子類中雖說...
C 區分介面繼承和實現繼承
利用public繼承基類,可以將繼承的結果分為兩類 函式介面繼承和函式實現繼承 宣告乙個純函式的目的是為了讓派生類只繼承函式介面 純虛函式有兩個突出的特性 它們必須被任何 繼承了它們 的具體類重新宣告,而且它們在抽象類中通常沒有定義 宣告非純虛函式的目的,是讓派生類繼承該函式的介面和預設實現 宣告非...
區分介面繼承和實現繼承
表面上的public繼承概念,其實經過嚴密的嚴查之後,會發現它由兩部分組成 函式介面繼承和函式實現繼承。這兩種繼承的差異,其實就是函式宣告與函式定義之間的差異。作為class的設計者,有時候你會希望derived class只繼承成員函式的介面 也就是宣告 有時候你又希望derived class同...