我曾多次看到有人提到这一点,但我不清楚这是什么意思。你什么时候,为什么要这么做?

我知道接口是做什么的,但我不清楚这一点的事实使我认为我错过了正确使用它们。

如果你要这样做

IInterface classRef = new ObjectWhatever()

你可以使用任何实现IInterface的类吗?你什么时候需要这样做?我能想到的唯一一件事是,如果你有一个方法,你不确定什么对象将被传递,除了它实现IInterface。我不知道你需要多久做一次。

另外,如何编写一个方法来接受实现接口的对象呢?这可能吗?


当前回答

If you program in Java, JDBC is a good example. JDBC defines a set of interfaces but says nothing about the implementation. Your applications can be written against this set of interfaces. In theory, you pick some JDBC driver and your application would just work. If you discover there's a faster or "better" or cheaper JDBC driver or for whatever reason, you can again in theory re-configure your property file, and without having to make any change in your application, your application would still work.

其他回答

“编程到接口”意味着不要直接提供硬代码,这意味着你的代码应该在不破坏之前功能的情况下进行扩展。只是扩展,而不是编辑前面的代码。

面向接口编程非常棒,它促进了松耦合。正如@lassevk提到的,控制反转是一个很好的应用。

此外,研究SOLID原则。这是一个系列视频

它通过硬编码(强耦合示例),然后查看接口,最后进展到IoC/DI工具(NInject)。

接口编程与我们在Java或。net中看到的抽象接口完全没有关系。它甚至不是面向对象的概念。

它的意思是不要乱动对象或数据结构的内部结构。使用抽象程序接口(API)与数据交互。在Java或c#中,这意味着使用公共属性和方法,而不是原始字段访问。对于C语言来说,这意味着使用函数而不是原始指针。

EDIT:对于数据库,这意味着使用视图和存储过程,而不是直接访问表。

短篇故事:一个邮递员被要求挨家挨户地接收写有地址的信封(信件、文件、支票、礼品卡、申请书、情书)。

假设没有封面,让邮递员挨家挨户地接收所有的东西,然后交给其他人,邮递员会感到困惑。

所以最好用封面(在我们的故事中是接口)包装它,然后他就会很好地完成他的工作。

现在邮差的工作只是收和送封皮(他不关心封皮里面有什么)。

创建一个接口类型,而不是实际类型,而是使用实际类型实现它。

创建一个接口意味着你的组件可以很容易地适应其余的代码

我给你们举个例子。

你有一个plane界面,如下所示。

interface Airplane{
    parkPlane();
    servicePlane();
}

假设在平面的Controller类中有这样的方法

parkPlane(Airplane plane)

and

servicePlane(Airplane plane)

在您的程序中实现。它不会破坏你的代码。 我的意思是,只要它接受参数plane,它就不需要改变。

因为它将接受任何飞机,不管实际类型,飞行员,高空飞行,战斗机等。

同样,在集合中:

列表> <飞机飞机;//会占用你所有的飞机。

下面的例子将帮助您理解。


你有一架战斗机来执行它,所以

public class Fighter implements Airplane {

    public void  parkPlane(){
        // Specific implementations for fighter plane to park
    }
    public void  servicePlane(){
        // Specific implementatoins for fighter plane to service.
    }
}

HighFlyer和其他类也是如此:

public class HighFlyer implements Airplane {

    public void  parkPlane(){
        // Specific implementations for HighFlyer plane to park
    }

    public void  servicePlane(){
        // specific implementatoins for HighFlyer plane to service.
    }
}

现在假设你的控制器类多次使用AirPlane,

假设你的控制器类是ControlPlane,如下所示,

public Class ControlPlane{ 
 AirPlane plane;
 // so much method with AirPlane reference are used here...
}

神奇的是,你可以在不改变ControlPlane类代码的情况下,尽可能多地创建新的AirPlane类型实例。

你可以添加一个实例…

JumboJetPlane // implementing AirPlane interface.
AirBus        // implementing AirPlane interface.

您也可以删除以前创建的类型的实例。

在Java中,这些具体类都实现了CharSequence接口:

神健壮健壮健壮健壮

除了Object之外,这些具体的类没有共同的父类,因此它们之间没有任何联系,除了它们各自都与字符数组有关,表示或操作这些字符。例如,String对象实例化后,String的字符不能被更改,而StringBuffer或StringBuilder的字符可以被编辑。

然而,这些类中的每一个都能够适当地实现CharSequence接口方法:

char charAt(int index)
int length()
CharSequence subSequence(int start, int end)
String toString()

在某些情况下,曾经接受String的Java类库类已经修改为现在接受CharSequence接口。因此,如果你有一个StringBuilder实例,而不是提取一个String对象(这意味着实例化一个新的对象实例),它可以在实现CharSequence接口时直接传递StringBuilder本身。

某些类实现的Appendable接口对于任何可以将字符追加到底层具体类对象实例的实例的情况都具有大致相同的好处。所有这些具体类都实现了Appendable接口:

BufferedWriter, CharArrayWriter, CharBuffer, FileWriter, FilterWriter, LogStream, OutputStreamWriter, PipedWriter, PrintStream, PrintWriter, StringBuffer, StringBuilder, StringWriter, Writer