在我的开发学习中,我觉得我必须学习更多关于接口的知识。
我经常读到它们,但我似乎无法理解它们。
我读过这样的例子:动物基类,IAnimal接口的东西,如“Walk”,“Run”,“GetLegs”等-但我从来没有工作过,觉得“嘿,我应该在这里使用接口!”
我错过了什么?为什么这个概念对我来说这么难理解!我只是害怕这样一个事实,我可能从来没有意识到一个具体的需要-主要是由于一些缺失的理解他们!这让我觉得我作为一名开发人员缺少了一些东西!如果有人有过这样的经历,并取得了突破,我会很感激一些关于如何理解这个概念的建议。谢谢你!
一个代码示例(结合了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的抽象基类)。但是考虑到您需要使用第三方记录器,它迫使您使用基类(假设它公开了您需要使用的受保护的方法)。由于语言不支持多重继承,您将无法使用抽象基类方法。
底线是:尽可能使用接口来获得代码的额外灵活性。您的实现不那么受约束,因此它能更好地适应变化。
假设你想要模拟当你试图睡觉时可能发生的烦恼。
接口前的模型
class Mosquito {
void flyAroundYourHead(){}
}
class Neighbour{
void startScreaming(){}
}
class LampJustOutsideYourWindow(){
void shineJustThroughYourWindow() {}
}
正如你清楚地看到的,当你试图睡觉时,许多“事情”都可能令人讨厌。
使用没有接口的类
但是在使用这些类时,我们遇到了一个问题。他们毫无共同之处。您必须分别调用每个方法。
class TestAnnoyingThings{
void testAnnoyingThinks(Mosquito mosquito, Neighbour neighbour, LampJustOutsideYourWindow lamp){
if(mosquito != null){
mosquito.flyAroundYourHead();
}
if(neighbour!= null){
neighbour.startScreaming();
}
if(lamp!= null){
lamp.shineJustThroughYourWindow();
}
}
}
带有接口的模型
为了克服这个问题,我们可以引入一个iterface
interface Annoying{
public void annoy();
}
并在类中实现它
class Mosquito implements Annoying {
void flyAroundYourHead(){}
void annoy(){
flyAroundYourHead();
}
}
class Neighbour implements Annoying{
void startScreaming(){}
void annoy(){
startScreaming();
}
}
class LampJustOutsideYourWindow implements Annoying{
void shineJustThroughYourWindow() {}
void annoy(){
shineJustThroughYourWindow();
}
}
接口使用
这将使这些类的使用更容易
class TestAnnoyingThings{
void testAnnoyingThinks(Annoying annoying){
annoying.annoy();
}
}
如果浏览. net Framework程序集并深入到任何标准对象的基类中,您将注意到许多接口(名为ISomeName的成员)。
Interfaces are basically for implementing frameworks, large or small. I felt the same way about interfaces until I wanted to write a framework of my own. I also found that understanding interfaces helped me learn frameworks much more rapidly. The moment that you want to write a more elegant solution for just about anything, you will find that an interface makes a lot of sense. It's like a method of letting a class put on the appropriate clothes for the job. More importantly, interfaces allow systems to become much more self-documenting, because complex objects become less complex when the class implements interfaces, which helps to categorize its functionality.
类在希望能够显式或隐式地参与框架时实现接口。例如,IDisposable是一个公共接口,它为流行且有用的Dispose()方法提供方法签名。在框架中,您或其他开发人员需要知道的关于类的所有信息是,如果它实现了IDisposable,那么您就知道((IDisposable)myObject). dispose()可用于清理目的。
经典示例:在没有实现IDisposable接口的情况下,你不能在c#中使用"using()"关键字构造,因为它要求任何指定为参数的对象都可以隐式转换为IDisposable。
复杂的例子:
一个更复杂的例子是System.ComponentModel.Component类。这个类同时实现了IDisposable和IComponent。大多数(如果不是全部的话)具有与之关联的可视化设计器的. net对象实现了IComponent,以便IDE能够与组件交互。
CONCLUSION:
As you become more familiar with the .NET Framework, the first thing you will do when encountering a new class in the Object Browser or within the .NET Reflector (free) tool (http://www.red-gate.com/products/reflector/) is to check to see which class it inherits from and also the interfaces that it implements. .NET Reflector is even better than the Object Browser because it lets you see the Derived classes as well. That allows you to learn about all objects that derive from a particular class, thereby potentially learning about framework functionality that you did not know existed. This is particularly significant when updated or new namespaces are added to the .NET Framework.