2008-12-18 64 views
12

我真的不知道如何標題這個問題,但基本上我有一個這樣的接口:使用Interface +抽象類的繼承設計。良好的做法?

public interface IFoo 
{ 
    string ToCMD(); 
} 

幾個absract類的其中實現的IFoo,如:

public abstract class Foo : IFoo 
{ 
    public abstract string ToCMD(); 
} 

public abstract class Bar : IFoo 
{ 
    public abstract string ToCMD(); 
} 

然後繼承的類Foo和酒吧:

public class FooClass1 : Foo 
{ 
    public override string ToCMD() 
    {return "Test";} 
} ///there are about 10 foo classes. 

public class BarClass : Bar 
{ 
    public override string ToCMD() 
    {return "BarClass";} 
} ///about the same for bar classes. 

我這樣做,這樣,當我有喜歡我的自定義列表:

public class Store<T> : List<T> where T : IFoo {} 

然後,我可以限制進入它的類型,但通過接口,它仍然會採取任何類型的IFoo。

喜歡的東西:

Store<Foo> store = new Store<Foo>(); //Only Foo types will work. 
store.Add(new FooClass1()); //Will compile. 

Store<IFoo> store = new Store<IFoo>(); //All IFoo types will work. 
store.Add(new FooClass1()); //Will compile. 
store.Add(new BarClass()); //Will compile. 

我的問題是:這是要對這個的好方法嗎?或者,還有更好的方法?

編輯:圖片 - > alt text

回答

6

需要一個繼承鏈是有問題的,一般。

但是一個抽象基類的接口相結合的具體情況。我這樣看:

如果你有一個抽象基類這樣,你也應該有相應的接口。如果你有一個接口,那麼只在繼承鏈是合理的地方使用抽象基類。這就是說,如果我正在編寫一個庫,並且這是我的API /框架的一部分,我通常會包含一個可用作基類的「默認實現」。它將在可能的情況下以一種簡單而通用的方式實現接口方法,剩下的則讓繼承者根據需要實現/覆蓋。

這只是該庫的一個便利功能,通過提供一個功能示例來幫助那些想要實現該接口的人,這個示例可能涵蓋了他們已經實現的大部分功能。

簡而言之,接口比基類更有價值,但基類可以節省大量時間並減少錯誤的接口實現。

1

好了,這就是其中的關鍵字是什麼。您可能需要評估您的對象模型以確保繼承的深度是必要的。深層次的繼承層次往往會使項目複雜化,並且通常是一面紅旗,但這取決於情況。

通常,您不需要抽象類來提供您正在討論的列表的功能,並且接口是指定類型限制的'首選'方法。如果您想封裝常用功能,我只會使用您的類的抽象版本。

簡短回答:確保你不會繼承瘋狂。

希望有幫助!

1

你也可以使用接口。沒有理由使用抽象類。

public interface Foo : IFoo 
{ 
} 

public interface Bar : IFoo 
{ 
} 
+0

我不確定使用空接口是個好主意。是嗎? – 2008-12-18 01:56:30

0

我不太清楚,如果這是你在找什麼,但也許你想要做的是報廢的接口一起,做到這一點:

abstract class Base 
{ 
    public abstract string ToCMD(); 
} 

abstract class Foo : Base { } 

abstract class Bar : Base { } 

希望你有其他成員FooBar類!這將允許您通過Base限制您的自定義收集或僅使用普通List<Base>

1

你需要接口;你可能會也可能不需要抽象類。一般來說,如果你可以在基類中提供一些有用的行爲,那麼提供一個基類;如果基類本身並不完整,然後使之抽象(在VB中的說法爲MustInherit)

否則,接口足以滿足