我们为什么要使用接口?仅用于标准化吗?[关闭]


79

我们为什么要使用接口?

它仅用于标准化吗?


1
而不是...?界面有很多用途...
Jason 2010年

6
我真的希望人们不要在非c#特定的帖子上放置c#这样的标签。这是一个非常好的问题,我可能会错过它,因为c#是一个忽略的标记。
泰勒·卡特

Answers:


171

接口目的

  • 创建松耦合软件
  • 通过合同支持设计(实施者必须提供整个接口)
  • 允许可插拔软件
  • 允许不同的对象轻松交互
  • 相互隐藏类的实现细节
  • 促进软件重用

类比1:与美国的航天飞机一样,俄罗斯的联盟号飞船和中国的神舟5号飞船都可以对接国际空间站,因为它们实现了相同的对接接口。(这只是一个例子-我不知道这在现实生活中是否属实,但是为了举例说明,让我们暂缓怀疑)

类比2:就像您可以将各种计算机显示器插入家用计算机一样。您可以将壁挂式电视插入其中,也可以插入旧的CRT(较厚的CRT),20英寸的纯平屏幕或盲文机,以使盲人可以通过触摸“看到”盲文。这些各种/不同的设备与您的设备兼容计算机,因为它们都同意接口标准。

C#接口的详细信息-使用C#/ OOP接口,您可以做的事情是一样的,但是看不见的/虚拟的。

您对标准化的看法是正确的,但在灵活性可扩展性可扩展性可维护性可重用性可测试性功能方面都是对的

(您使用软件界面的次数越多,对这些“流行语”的理解就越多。请务必考虑现实世界中的界面,因为它们对我们的作用同样出色。)


18
您忽略了我最喜欢的接口使用:可测试性。如果我有两个类A和B,并且A.foo调用B.bar,那么只要B实现一个接口并且可以“注入”到A中,那么我就可以使用模拟,伪造或存根类来代替当真正的B。当A.foo根据B.bar的返回值更改其行为时,这尤其有用。(说B.bar返回一个布尔值。A.foo可能有一个带有else子句的if(B.bar)语句。)在B中使用接口可以使我创建嘲笑B,fakeB和/或stubB,从而可以测试什么当B.bar返回true或false时发生。
aridlehoover

@Alan R-可测试性已添加。谢谢。
约翰·K

1
公认的答案是最重要的,令人耳目一新的是,由于大多数框架设计指南材料都无法解释或理解该概念,因此该概念没有被放弃。只是补充一点,如果您正在认真使用泛型,那么我不知道没有它们会怎样。
rama-jka toti

6
+1standardization, but also flexibility, scalability, extensibility, maintainability, reusability, testability and power.
拉维

29

接口用于描述已实现的功能。因此,您可以将实现同一接口的多个对象视为该接口的类型。

例如:

public interface IMyInterface{
    public void DoFirst();
    public int DoSecond();
}


public class A : IMyInterface{
   //class has to implement DoFirst and DoSecond
   public void DoFirst(){
     Console.WriteLine("Blubb1");  
   }

   public int DoSecond(){
     Console.WriteLine("Blubb2");
     return 2;  
   }
}

public class B : IMyInterface{
   //class has to implement DoFirst and DoSecond
   public void DoFirst(){
     Console.WriteLine("Blibb1");  
   }

   public int DoSecond(){
     Console.WriteLine("Blibb2");  
     return 4;
   }
}

这些类以几种方式实现Interface。但是您可以将它们用作IMyInterface。例如:

public static void DoMethodsInInterface(IMyInterface inter){
    inter.DoFirst();
    inter.DoSecond();
}


public static void main(){

   DoMethodsInInterface(new A());
   DoMethodsInInterface(new B());
   //Or use it in a List
   List<IMyInterface> interlist = new List<IMyInterface>();
   interlist.Add(new A());
   interlist.Add(new B());
   foreach(IMyInterface inter in interlist){
      inter.DoFirst();
   }

}

我希望这可以弄清楚为什么接口有用。


2
这个问题与一个问题相关联,该问题询问为什么要使用接口而不是简单地让成员执行适当的功能等,您的答案最接近于回答那个问题。如果两个不相关的类都具有method Woozle,那么任何想要接受对任何一个类的引用的代码,Woozle都必须知道它正在处理哪个类,并且只能对其知道的类进行处理Woozle。相反,如果两个类都实现IWoozler,则IWoozler可以Woozle在不知道其确切类型的情况下给定任何代码。
超级猫

这个答案比我见过的要好得多。这与对象可以做什么有关。接口指定了一组与对象有关的动作,而没有规定那些动作中发生的事情显然是对象特定的。
m12lrpv

5

这是用于接口:),以便您可以在各种事物之间进行接口,当您拥有

  • 相同内容的多种实现
  • 当您将接口应用于多个不同的类时,因为您需要某种约定,这些类将能够做一些事情或具有某些功能

3

这是高级视图...

接口在信息隐藏的概念中起着重要作用。

它们基本上可以帮助您隐藏类的实现细节,以便调用类不会依赖于该实现。因此,通过使用接口,您可以在不更改调用类的情况下修改实现。这又反过来限制了代码的复杂性,并从长远来看使维护变得更容易

当我第一次开始理解接口时,它们被解释为“提供类说明的合同”。不知道这会帮助你,但如果你认为一个接口的一辆汽车,你可以说,它驱动休息,并轮流。因此,只要它使我从A点到达B点,我实际上就不必知道这些功能是如何实现的。


2

在诸如C#/ Java之类的语言中使用接口的主要原因是,因为这些语言不支持多重(类)继承(请参阅多重继承的确切问题是什么?)。

但是允许多个(接口)实现,从而允许以不同方式使用类。


1
托管语言的接口不能替代多重继承。而且,即使在支持多重继承的语言中,没有实现的接口概念也很实用。(请参阅依赖项注入。)
aridlehoover 2010年

1
-1并不是经过深思熟虑的,还是您真的不了解C#或Java?
约翰·桑德斯

我想说的是,在C ++中,可以使用纯抽象类代替接口。您可以在Java / C#中通过接口使用C ++中的纯抽象类来完成大多数操作。在C ++中,如果您希望一个类具有多种行为,则可以继承多个纯抽象类。但是您不能在Java / C#中做到这一点。我并不是说接口不是“有用的”,而是说更多的是:没有多接口继承,像Java和C#这样的语言就不会真正成为面向对象的编程语言。(它们不允许多重类继承或混合)
Catalin DICU 2010年

1
+1本质上,这是C#和Java的辛苦发现。如果您尝试通过避免多重继承来简化,那么您只会在其他地方创建复杂性。由于缺乏统一的基础方法,您最终会遇到更复杂的情况。请参见Cr编程语言第三版1.9接口中的Krzystof Cwalina的注释,该内容正是如此。到目前为止,如果允许类的多重继承,则C#和Java中仍然存在未解决的问题,这些问题将具有简单的解决方案。
Daniel Earwicker 2010年

-1的继承和接口确实有很大的不同。
肯尼,2010年

2

接口有些尴尬。他们相信,通过合同支持设计,相同的名称和实现的接口意味着相同的行为。仅依靠API文档,此方法才有效,必须进行人工检查。这会使接口太弱。解决该问题的一种方法可能是正式规范。另一方面,接口太强,太严格。您不能开发经常妨碍重用的接口。这可以通过协议来解决-协议是一种动态语言的机制,可以发送消息(调用方法),并且当接收者不支持该消息时,将调用标准回调。具有约束的具体协议会更好。


1

考虑远程处理...

这里有一个客户端和一个服务器。可以说,它们实际上是由互联网隔开的。客户端正在调用实际执行在服务器上的方法。从客户端的角度来看,客户端对服务器中执行执行的对象一无所知。但是,它知道调用哪种方法。因为在构建客户端程序时,我们仅接触到接口(或合同)。我们没有接触到实际存在于服务器上的整个对象。尝试在.net远程处理中做一些演示应用程序,其余的您会发现的。编程愉快。


0

为什么要使用接口?

有些语言实现使用虚函数表,并丢弃大多数类型的信息则很难多态的方法调用来定义接口。

所以有时候我们只是使用接口,因为语言设计需要它。


0

从接口开始,您可以实现proxy,从而允许在调用具体实现方法时进行延迟加载或执行一些验证。



0

接口提供了原型模式,该模式只包含特定行为的功能声明。

如果要在类中实现此行为,则必须在类中实现此接口,则类具有此行为功能,或者可以具有多个行为。

因为类可以实现多个接口。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.