在我的开发学习中,我觉得我必须学习更多关于接口的知识。
我经常读到它们,但我似乎无法理解它们。
我读过这样的例子:动物基类,IAnimal接口的东西,如“Walk”,“Run”,“GetLegs”等-但我从来没有工作过,觉得“嘿,我应该在这里使用接口!”
我错过了什么?为什么这个概念对我来说这么难理解!我只是害怕这样一个事实,我可能从来没有意识到一个具体的需要-主要是由于一些缺失的理解他们!这让我觉得我作为一名开发人员缺少了一些东西!如果有人有过这样的经历,并取得了突破,我会很感激一些关于如何理解这个概念的建议。谢谢你!
把接口想象成一个契约。这是一种说法,“这些类应该遵循这些规则。”
所以在IAnimal的例子中,它是一种说,“我必须能够在实现IAnimal的类上调用Run, Walk等。”
为什么这个有用?您可能希望构建一个函数,该函数依赖于必须能够在对象上调用Run和Walk这一事实。你可以有以下内容:
public void RunThenWalk(Monkey m) {
m.Run();
m.Walk();
}
public void RunThenWalk(Dog d) {
d.Run();
d.Walk();
}
... 对所有你知道能跑能走的物体重复这一步骤。然而,在你的IAnimal接口中,你可以像下面这样定义函数:
public void RunThenWalk(IAnimal a) {
a.Run();
a.Walk();
}
通过根据接口编程,您实际上是信任类来实现接口的目的。所以在我们的例子中,想法是“我不在乎他们怎么跑和走,只要他们能跑和走。”只要他们履行协议,我的RunThenWalk就有效。它在不了解任何其他课程的情况下运行得很好。”
在这个相关的问题上也有很好的讨论。
一个代码示例(结合了Andrew的代码和我的额外的关于“接口的目的是什么”的代码),也说明了为什么在不支持多重继承的语言(c#和java)上接口而不是抽象类:
interface ILogger
{
void Log();
}
class FileLogger : ILogger
{
public void Log() { }
}
class DataBaseLogger : ILogger
{
public void Log() { }
}
public class MySpecialLogger : SpecialLoggerBase, ILogger
{
public void Log() { }
}
注意,FileLogger和DataBaseLogger不需要接口(可以是Logger的抽象基类)。但是考虑到您需要使用第三方记录器,它迫使您使用基类(假设它公开了您需要使用的受保护的方法)。由于语言不支持多重继承,您将无法使用抽象基类方法。
底线是:尽可能使用接口来获得代码的额外灵活性。您的实现不那么受约束,因此它能更好地适应变化。
使用接口有很多目的。
Use in polymorphic behavior. Where you want to call specific methods of a child class with an inteface having a reference to the child class.
Having a contract with classes to implement all of the methods where it is necessary, like most common use is with COM objects , where a wrapper class is generated on a DLL which inherits the interface; these methods are called behind the scenes, and you just need to implement them but with the same structure as defined in the COM DLL which you can only know through the interface that they expose.
To reduce memory usage by loading specific methods in a class. Like if you have three business objects and they are implemented in a single class, you can use three interfaces.
例如IUser, IOrder, IOrderItem
public interface IUser()
{
void AddUser(string name ,string fname);
}
// Same for IOrder and IOrderItem
//
public class BusinessLayer: IUser, IOrder, IOrderItem
{
public void AddUser(string name ,string fname)
{
// Do stuffs here.
}
// All methods from all interfaces must be implemented.
}
如果你只想添加一个用户,可以这样做:
IUser user = new (IUser)BusinessLayer();
// It will load all methods into memory which are declared in the IUser interface.
user.AddUser();