有a look at this blog。有時候,結合這兩個是非常有用的:
「好的語言設計通常會導致一些良好定義的簡單 元,可以在直觀和智能 方式一起結合 相反,不良的語言 設計通常會導致英寸許多臃腫 結構沒有發揮好 在一起。
的「抽象」和「越權」在C#中的關鍵字 是一個很好的例子。 他們都有簡單的定義,但 它們可以組合起來表達更復雜的概念。
假設你有一個類層次結構: Ç的B派生,而B派生從 答:有一個抽象方法foo()和 粘粘()。這裏有兩種情況,其中 「抽象覆蓋」會出現。 1) 假設B只想實現 Goo(),並讓C實現Foo()。 B 可以將Foo()標記爲「抽象覆蓋」。 這清楚地表明B 可以識別Foo()在 基類A中聲明,但它期望另一個 派生類來實現它。 2)讓我們假設B想強制C改爲 重新實現Foo(),而不是使用A的 定義Foo()。乙標記美孚()作爲 二者覆蓋(這意味着乙 識別符()中的 基類被聲明)和抽象(這意味着派生C類提供一種 實施 乙力;不管是A 已經提供了一種實現)。 這是我最近的博客 這裏的一個條目。在該示例中, A = TextReader,Foo = ReadLine,B = a 幫助程序類,C =某些類要實現ReadLine()而不是 Read()。現在TextReader已經有一個基於Read()的ReadLine() 的默認實現 ,但我們想要以其他方式去 。我們希望基於 的派生類實現 ReadLine()基於 實現Read()。因此,B提供了一個實現Read()的函數,它使用ReadLine(),然後將ReadLine() 標記爲「抽象覆蓋」,以強制C重新定義ReadLine(),而不是從TextReader中選取 。
總之,「抽象覆蓋」是 酷,不是因爲它是一個還更 語言功能表達一些 複雜的角落情況;這很酷,因爲 它不是一種語言功能。 整潔的部分是,你並不真的 需要考慮任何這一點。您 只使用單個基本概念 自然,和複雜的東西 自動走到一起「
這是方案1我的示例代碼:
public abstract class A
{
public abstract void Foo();
public abstract void Goo();
}
public abstract class B : A
{
public abstract override void Foo();
public override void Goo()
{
Console.WriteLine("Only wanted to implement goo");
}
}
public class C : B
{
public override void Foo()
{
Console.WriteLine("Only wanted to implement foo");
}
}
而對於場景2我的示例代碼:
public abstract class A
{
public virtual void Foo()
{
Console.WriteLine("A's Foo");
}
public abstract void Goo();
}
public abstract class B : A
{
public abstract override void Foo();
public override void Goo()
{
Console.WriteLine("Only wanted to implement goo");
}
}
public class C : B
{
public override void Foo()
{
Console.WriteLine("Forced to implement foo");
}
}
在你的問題代碼是沒有用的,但這並不意味着抽象和覆蓋組合我沒用。
我不知道我的理解是什麼?增加一點編譯失敗的好處是什麼?另外,如果您的基類增加了另一種抽象方法,並且您不重構衍生產品,您將不會持續獲得此結果。 – LBushkin 2009-07-14 13:47:30
@LBushkin:是的,你不會找到補充......但如果您不另外擁有*任何*(注意您的代碼庫中的任何地方可能沒有具體的類),那麼添加另一個失敗點可能會非常有用。我不是說它會經常出現... – 2009-07-14 13:52:00
讚賞繼承樹(描述性代碼或*有意義的*評論)中的任何描述。繼承使得基類和派生類的交互有點神祕 - 尤其是如果(a)基類不是一個簡單的,精心設計的和集中的對象(b),如果維護者沒有寫出基類和派生類。繼承是偉大的,但可以被極大地濫用,使神奇的笨拙代碼 – STW 2009-07-14 13:56:19