我可以理解为什么要对接口而不是实现进行编程。但是,在以下示例中(我发现了很多):
public interface ISomething
{
void BlahOne(int foo);
void BlahTwo(string foo);
}
public class BaseSomething : ISomething
{
public void BlahOne(int foo)
{
//impl
}
public void BlahTwo(string foo)
{
//impl
}
}
public class SpecificSomethingOne : BaseSomething
{
public void SpecificOne()
{
//blah
}
}
public class SpecificSomethingTwo : BaseSomething
//and on..
目前的例子是我游戏中基于组件的实体系统。 (我有IComponent,Component,PosComponent等)。
但是,我看不出有ISomething的理由。名称可能看起来更好,但它似乎没有目的。我可以随时返回BaseSomething。
当您使用单个基本实现时,是否有理由拥有接口? (我可以看到IComparable或IEnumerable的使用)
编辑:对于稍微不同的场景(但仍然相关,不需要不同的问题),如果我假设我有所有的这个结构,如果我使用ISomething
作为参数会有很大的不同类型和变量与BaseSomething
相比?
答案 0 :(得分:13)
我更喜欢“懒惰设计” - 在需要时从BaseSomething
提取界面。在此之前,请保持简单并跳过它。
现在我可以想到只有一个实现时有一个接口的两个原因:
答案 1 :(得分:2)
对您的问题的正确答案是“取决于”。
你可以用许多不同的方式来看待它,而这一切都与视角有关。当您拥有一个具体或抽象的基类时,这意味着您的对象在功能上具有共同点。衍生对象以某种方式相互关联。接口允许您仅在功能合同中确认实现接口的每个对象将负责实现。
同样,当您再次编程接口时,您必须严格了解对象的功能,因为它实现了给定的接口。而且您无需担心每个对象在功能上如何实现这一点。
如果我说的话,这不是完全错误的 你的每个对象都是完全的 在谈到时是独立的 实现ISomething接口,因为SpecificSomethingOne和SpecificSomethingTwo不是从BaseSomeThing派生的,而是每个都实现了自己的ISomething。
您可以在同一事项上参考this answer。
答案 2 :(得分:1)
这不是必要的,但如果您想稍后扩展程序或者想要实现另一个Base-Class,那么它是一个更好的设计。 在你的情况下,我不会实现基类。如果您不想拥有默认行为,那么接口就可以了。如果您想要一个默认行为,那么只需编写没有接口的Base-Class
答案 3 :(得分:0)
如果您的BaseSomething是抽象的并且您实现了提供程序重载抽象方法的特定事物,那么在那时编程到它们的唯一方法是ISomething接口。但是,在您展示的示例中,除非您有多个基本实现,否则ISomething实际上没有理由。