C# 使用接口+抽象类的继承设计。好习惯?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/376642/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Inheritance design using Interface + abstract class. Good practice?
提问by Nathan W
I'm not really sure how to title this question but basically I have an interface like this:
我不太确定如何命名这个问题,但基本上我有一个这样的界面:
public interface IFoo
{
string ToCMD();
}
a couple of absract classes which implement IFoo like:
几个实现 IFoo 的抽象类,例如:
public abstract class Foo : IFoo
{
public abstract string ToCMD();
}
public abstract class Bar : IFoo
{
public abstract string ToCMD();
}
then classes which inherit Foo and Bar:
然后是继承 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.
I am doing this so that when I have my custom list like:
我这样做是为了当我有我的自定义列表时:
public class Store<T> : List<T> where T : IFoo {}
I then can restrict the types that go in it but by having the interface it will still take any type of IFoo.
然后我可以限制其中的类型,但通过拥有接口,它仍然可以采用任何类型的 IFoo。
Something like:
就像是:
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.
My question is: Is this an ok way of going about this? or is there a better way?
我的问题是:这是解决这个问题的好方法吗?或者,还有更好的方法?
EDIT: Picture->
编辑:图片->
采纳答案by Troy Howard
The need for an inheritance chain is questionable, in general.
一般来说,是否需要继承链是有问题的。
However the specific scenario of combining an abstract base class with an interface.. I see it this way:
然而,将抽象基类与接口结合的特定场景..我是这样看的:
If you have an abstract base class like this, you should also have a corresponding interface. If you have an interface, then use the abstract base class only where the inheritance chain is sensible.
如果你有这样的抽象基类,你也应该有相应的接口。如果你有一个接口,那么只在继承链合理的地方使用抽象基类。
That said, if I'm writing a library and this is part of my API/Framework, I will generally include a "default implementation" that can be used as a base class. It will implement the interface methods in a naive, general way, where possible, and leave the rest for inheritors to implement/override as needed.
这就是说,如果我正在写一个库,这是我的API / Framework的一部分,我一般会包括可以用作基类中的“默认的实现”。在可能的情况下,它将以一种朴素的、通用的方式实现接口方法,并将其余的留给继承者根据需要实现/覆盖。
This is just a convenience feature of the library though, to assist people who want to implement the interface by providing a functional example that may cover most of what they need to implement already.
不过,这只是该库的一个便利功能,通过提供一个功能示例来帮助想要实现接口的人,该示例可能涵盖他们已经需要实现的大部分内容。
In short, the interface is more valuable than the base class, but a base class might save a lot of time and reduce buggy interface implementations.
简而言之,接口比基类更有价值,但基类可能会节省大量时间并减少有缺陷的接口实现。
回答by Zachary Yates
Well, that's what the where keyword is for. You probably need to evaluate your object model to make sure that the depth of your inheritance is necessary. Deep inheritance hierarchies tend to complicate projects and are generally a red flag, but it depends on the situation.
嗯,这就是 where 关键字的用途。您可能需要评估您的对象模型以确保您的继承深度是必要的。深层继承层次结构往往会使项目复杂化,并且通常是一个危险信号,但这取决于具体情况。
Usually, you don't need the abstract class to pull off the functionality you're talking about with the lists, and interfaces are the 'preferred' method for specifying type restrictions. I'd only use the abstract version of your class if there is common functionality you want to encapsulate.
通常,您不需要抽象类来实现您正在谈论的列表功能,并且接口是指定类型限制的“首选”方法。如果您想要封装通用功能,我只会使用您的类的抽象版本。
Short answer: make sure you're not going inheritance crazy.
简短回答:确保您不会为继承发疯。
Hope that helps!
希望有帮助!
回答by gcores
You could also just use interfaces. There is no reason to use an abstract class.
你也可以只使用接口。没有理由使用抽象类。
public interface Foo : IFoo
{
}
public interface Bar : IFoo
{
}
回答by Andrew Hare
I am not quite sure if this is what you are looking for but perhaps what you want to do is scrap the interface all together and do this:
我不太确定这是否是您正在寻找的,但也许您想要做的是将界面全部废弃并执行以下操作:
abstract class Base
{
public abstract string ToCMD();
}
abstract class Foo : Base { }
abstract class Bar : Base { }
Hopefully you have other members in the Foo
and Bar
classes! This will allow you to either restrict your custom collection by Base
or just use a plain List<Base>
.
希望你Foo
和班里还有其他成员Bar
!这将允许您通过Base
或仅使用普通的List<Base>
.
回答by Steven A. Lowe
you need the interface; you may or may not need the abstract class.
你需要接口;您可能需要也可能不需要抽象类。
in general, if you can provide some useful behavior in a base class, then provide a base class; if the base class is not complete by itself then make it abstract (MustInherit in VB parlance)
一般来说,如果你可以在基类中提供一些有用的行为,那么就提供一个基类;如果基类本身不完整,则将其抽象化(VB 中的 MustInherit)
otherwise, the interface is sufficient
否则,接口就足够了