我不确定如何标题这个问题,但基本上我有这样的界面:
public interface IFoo
{
string ToCMD();
}
实现IFoo的几个absract类,如:
public abstract class Foo : IFoo
{
public abstract string ToCMD();
}
public abstract class Bar : IFoo
{
public abstract string ToCMD();
}
然后继承Foo和Bar的类:
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.
我的问题是:这是否可以解决这个问题?还是有更好的方法?
编辑:图片 - &gt;
答案 0 :(得分:6)
一般而言,对继承链的需求是值得怀疑的。
然而,将抽象基类与接口相结合的具体方案......我这样看:
如果你有这样的抽象基类,你也应该有一个相应的接口。如果你有一个接口,那么只在继承链合理的地方使用抽象基类。
那就是说,如果我正在编写一个库,这是我的API / Framework的一部分,我通常会包含一个可以用作基类的“默认实现”。它将尽可能以一种天真的,通用的方式实现接口方法,并让其余的继承者根据需要实现/覆盖。
这只是图书馆的一个便利功能,通过提供可能涵盖他们需要实施的大部分内容的功能性示例来帮助想要实现界面的人。
简而言之,接口比基类更有价值,但基类可能会节省大量时间并减少错误的接口实现。
答案 1 :(得分:2)
你需要界面;你可能需要也可能不需要抽象类。
一般来说,如果你可以在基类中提供一些有用的行为,那么提供一个基类;如果基类本身不完整,那么将其设为抽象(用VB说明MustInherit)
否则,界面就足够了
答案 2 :(得分:1)
嗯,这就是where关键字的用途。您可能需要评估对象模型以确保继承的深度是必要的。深度继承层次结构往往使项目复杂化,并且通常是一个红旗,但它取决于具体情况。
通常,您不需要抽象类来实现您与列表讨论的功能,而接口是指定类型限制的“首选”方法。如果您想要封装常用功能,我只会使用您的类的抽象版本。
简短回答:确保你不会继承疯狂。
希望有所帮助!
答案 3 :(得分:1)
您也可以使用界面。没有理由使用抽象类。
public interface Foo : IFoo
{
}
public interface Bar : IFoo
{
}
答案 4 :(得分:0)
我不太确定这是否是您正在寻找的东西,但也许您想要做的就是废弃所有界面并执行此操作:
abstract class Base
{
public abstract string ToCMD();
}
abstract class Foo : Base { }
abstract class Bar : Base { }
希望您在Foo
和Bar
课程中有其他成员!这样您就可以Base
限制自定义收藏,或者只使用普通List<Base>
。