我有一个派生自Interface的类。现在该类必须实现Interfaces +中的所有方法,它还定义了另外两个方法。 现在我的问题是,这样做的好处/用例是什么:
IMyInterface varInt= new ConcreteImp();
以上,
ConcreteImp varInt= new ConcreteImp();
我看到这个模式在代码块中的每个位置使用,但不确定为什么使用它。
答案 0 :(得分:2)
使用接口的好处在于减少部件对软件组件的具体实现的依赖性。在您发布的一行中,您将无法看到好处。可以从该界面的消费者中获益。
例如,假设您有一个接受类似Rent(IMovie)
的接口的方法。另一个人将能够编写Rent()
方法的实现,而不知道在调用方法时您将传递的IMovie
类型的细节。然后,您将能够创建多个不同的IMovie
实施方案,这些实施方案可能采用不同的结算方式,但Rent()
方法无需处理此问题。
void Rent(IMovie movie)
{
var price = movie.Price();
movie.MarkReserved();
}
public interface IMovie { }
public class Oldie : IMovie
{
private decimal _oldieRate = 0.8;
public decimal Price()
{
return MainData.RentPrice * _oldieRate;
}
public decimal MarkReserved()
{
_oldiesDb.MarkReserved(this, true);
}
}
public class Blockbuster : IMovie
{
private decimal _blockbusterRate = 1.2;
public decimal Price()
{
return MainData.RentPrice * _blockbusterRate ;
}
public decimal MarkReserved()
{
_regularDb.MarkReserved(this, true);
}
}
这是接口有用的原因示例,但不是很好的代码设计示例。
根据经验,您应该编写方法,以便它们需要最少的输入才能工作,并且它们的输出提供了其他人在调用时使用的尽可能多的信息。例如,看一下以下签名:
public List<Entity> Filter(IEnumerable<Entity> baseCollection){ ... }
此方法仅请求IEnumerable<Entity>
,因此它可以采用不同的集合类型,例如List<Entity>
,Entity[]
或某些工具返回的自定义类型。但是你返回List<Entity>
,这样你就不会将调用者限制为只有可枚举的元素。例如,她可以立即使用Linq返回值。
还有更多好处,例如在单元测试中,您可以在其中创建模拟对象,并告诉他们在与其余代码交互时如何表现。虽然,现在可以使用虚拟方法对类进行此操作。
答案 1 :(得分:1)
假设您希望代码中的其他位置能够将IMyInterface
的不同实现分配给varInt
变量。然后需要使用类型IMyInterface
声明该变量。
或者,如果您想向任何代码读者明确表示您打算使用varInt
定义的所有接口都使用IMyInterface
定义的接口,那么类型声明就会明确说明。
答案 2 :(得分:1)
当您需要在派生类使用界面中强制执行功能时。
当你需要将数据从超类传递给子类时,你就使用了具体的类。它是接口和子类背后的基本oop理念。
答案 3 :(得分:0)
在你的具体例子中,我会说它并不重要,因为你使用new
并创建一个具体的类型。当您开始使用dependency injection时,它开始变得更有用。
更有用的场景如下所示:
public SomeResultType DoSomething(ISomeType obj)
{
//to something with obj
// return someResultType
}
只要它实现ISomeType
,就可以使用任何类型调用上述内容。但是在使用new
关键字的示例中,我会使用var
。您仍然可以将其视为它实现的类型,因为它继承了该类型。
答案 4 :(得分:0)
假设IMyInterface有“Draw”方法,现在所有派生类都必须实现“Draw”方法。如果你有一个“引擎”类,其方法是“渲染(IMyInterface形状)”,你只需调用“绘图”方法,无论形状如何。每个形状都按照自己的意愿画画。 你可以看看设计模式,你可以看到界面的魔力;)