在OOP中创建接口基础架构背后的理念是什么?

时间:2012-12-06 16:39:38

标签: c# java oop interface

我认为我们出于某些原因发明了东西:OOP之所以出现,是因为程序式编程不符合我们的需求;接口也是如此,因为像Abstract这样的其他OOP功能无法满足我们的需求。

有很多关于界面 CAN DO 如何使用的文章和指南,但是,我我想知道Interface的创建背后的实际理念是什么?为什么我们需要接口?

5 个答案:

答案 0 :(得分:3)

从概念上讲,接口是合同。这是一种说法,任何实现此接口的东西都能够这些东西

不同的语言具有接口可以定义的不同内容,以及定义它们的不同方式,但这个概念仍然存在。

使用接口可以让您不关心 某些特定任务是如何完成的;它允许您确保 它已完成。

通过允许实现不同,并允许代码仅定义所需内容的最小子集,它允许您概括代码。

也许您想编写一种方法来在屏幕上编写一系列数字。您不希望在任何(许多)其他常用数据结构上为数组,集合,树执行此操作。您不需要 care 无论您是处理数组还是链接列表,您只需要一些方法来获取一系列项目。接口允许您仅定义所需内容的最小集合,假设使用getNextItem方法,然后如果所有这些数据结构都实现了该方法和接口,则可以使用一种通用方法。这比为您想要使用的每种类型的数据结构编写单独的方法更容易 。 (这不是唯一使用的接口,只是一个常见的接口。)

答案 1 :(得分:2)

在Java中,类只能从一个类继承,但它们可以实现多个接口。接口类似于抽象类,但是如果类扩展了抽象类,那么该类不能扩展任何其他类。接口解决了这个问题,你可以使一个类扩展一个抽象类并实现许多接口。

答案 2 :(得分:0)

我完全赞同susomena,但这并不是你使用接口时获得的唯一好处。

例如。在我们当前的应用中,模拟在单元测试中起着重要作用。单元测试的理念是,您应该只测试该单元本身的代码。但是,有时候还有其他依赖关系,“被测单元”(SUT)需要得到。也许这种依赖有其他依赖性等等。因此,您不必复杂地构建和配置依赖关系树,而只是伪造这种特定的依赖关系。需要使用类的接口来设置许多模拟框架,SUT依赖于该接口。通常可以模拟具体类,但在我们的例子中,由于构造函数调用,模拟具体类会导致单元测试的奇怪行为。但是模拟接口没有,因为接口没有构造函数。

我选择抽象类实现的个人理念是构建一个分层类构造,其中需要一些抽象基类的默认行为。如果没有任何默认行为,派生类应该继承,我没有看到任何不在抽象类实现上选择接口的要点。

这是另一个(不太好)如何选择一个而不是另一个技术的例子。想象一下,你有很多动物类,如CatDog。抽象类Animal可能实现此默认方法:

public abstract void Feed() 
{
    Console.WriteLine("Feeding with meat"); 
}

没关系,如果你有很多动物,那对肉很好。对于少量不喜欢肉类的动物,你只需要重新实现Feed()的新行为。

但是,如果这些动物是一个有点美食家怎么办?并且要求是每只动物都能获得它的首选食物吗?我宁愿在那里选择一个接口,因此程序员必须为Feed()的每一种类型实现IAnimal方法。

答案 3 :(得分:0)

IMO描述界面的最佳文本是ISP from Robert Martin

接口的真正力量来自于以下事实:(1)您可以将对象视为具有许多不同类型(因为类可以实现不同的接口)和(2)处理来自不同层次树的对象,就好像它们一样具有相同的类型(因为没有相关的类可以实现相同的接口)。

如果你有一个带有某种接口类型参数的方法(例如,一个Comparable),这意味着这个方法可以接受任何实现该接口“忽略”该类的对象(例如,一个String或一个Integer,实现Comparable的两个不相关的类。)

因此,接口是一个比抽象类更强大的抽象。

答案 4 :(得分:0)

接口被引入OOP,因为它在the producer consumer paradigm中使用的唯一原因。让我用一个例子解释一下......
假设有一家供应商为所有大型汽车公司供应轮胎。汽车公司被认为是消费者,轮胎供应商是生产者。现在消费者指示生产者必须生产轮胎的各种规格(例如直径,轮距等);制作人必须严格遵守所有这些规范。

让我们从这里得到一个类比OOP ...让我们开发一个应用程序来实现一个堆栈,你正在为它开发UI;让我们假设您正在使用堆栈库(作为.dll或.class)来实际实现堆栈。在这里,您是消费者,实际编写堆栈程序的人是生产者。现在,您指定堆栈的各种规格,说它应该有推送元素和 pop 元素的规定以及 peep 在当前堆栈指针处。您还可以通过指定返回类型和参数(函数原型)来指定访问这些规定的接口,以便您知道如何在应用程序中使用它们。
实现这一目标的最简单方法是创建一个接口并要求生成器实现此接口。因此,无论生产者使用什么逻辑(只要您的需求以某种方式满足,您都不会对实现感到困扰),他将实现具有精确返回类型的push,pop和peep方法和参数
换句话说,您通过让他实现您的界面,使制作人严格遵守您的规范和访问您需求的方式。如果他没有实现你的界面,你不会只接受任何供应商的堆栈;因为你不能确定它是否适合你的确切需要。

 class CStack implements StackInterface
 {//this class produced by the producer must have all three method implementation
  //interface defined by the consumer as per his needs
 bool push(int a){
    ...
 }
 int pop(){
   ....
 }
 int peep(){
   ...
 }
 }