23

假设你有一个接口

public interface Change {

    void updateUser();
    void deleteUser();
    void helpUser();

}

我读过接口是Java实现多重继承的方式。你实现一个接口,然后你就可以访问它的方法。我不明白的是,这些方法在接口中没有任何主体,所以你需要在你的类中给它们一个主体。因此,如果您的接口由多个类实现,则需要为该方法提供多个类中的主体。为什么这比在你的类中只使用单独的方法而不实现接口更好?

4

6 回答 6

59

我在大学的教授曾经讲过一个很好的轶事来描述多态性和封装性。它是这样的。


这里有人知道汽水机是如何工作的吗?(暗示我们为什么要谈论这个困惑的目光。)不?让我告诉你。

你把零钱放进去,机器里面有个小猴子,它会清点你所有的零钱,以确保你投入了足够的钱。当你按下你的汽水按钮时,一个小灯会亮起,告诉猴子你按下了哪个按钮,如果你输入了正确的零钱,它就会抓住你的选择,把它扔进小洞里,让你拿​​你的汽水。

这就是封装的概念。我们隐藏了汽水机的实现。除非它有一个花哨的、透明的窗户让你看到里面,否则你真的不知道它是如何工作的。你所知道的就是你投入一些现金,按下一个按钮,如果投入足够,你就会得到饮料。

另外,您知道如何使用汽水机的界面,因此只要机器的界面遵循通常的汽水机界面,您就可以使用它。这称为接口契约。这台机器可以将来自南极洲的饮料带到传送带上,供您随意使用,只要您拿到饮料,天气很冷,您就可以取回零钱。

多态性是指当您使用汽水机界面时,它可能会做不同的事情。这就是封装和多态密切相关的原因。在多态中,您所知道的只是您正在使用一个SodaMachine可以更改的实现,因此可以在幕后完成不同的事情。这导致了多态性的驱动概念,它是一个对象的能力,SodaMachine即实际作为 aMonkeySodaMachine和 a 的能力ConveyorSodaMachine取决于接口背后的实际机器。


可能不是逐字逐句,但足够接近。本质上它归结为两个概念:多态性封装。如果您需要澄清,请告诉我。

于 2013-07-16T20:26:43.047 回答
13

为什么这比在你的类中只使用单独的方法而不实现接口更好?

因为如果一个类C实现了一个 interface I,你可以C在需要 an 的时候使用 a I。如果您不实现接口,则无法执行此操作(即使您提供了接口要求的所有适当方法):

interface I {
    void foo();
}

class C1 implements I {
    public void foo() {
        System.out.println("C1");
    }
}

class C2 {  // C2 has a 'foo' method, but does not implement I
    public void foo() {
        System.out.println("C2");
    }
}

...

class Test {
    public static void main(String[] args) {
        I eye1 = new C1();  // works
        I eye2 = new C2();  // error!
    }
}
于 2013-07-16T20:10:32.147 回答
9

它将调用者的期望与实现分开。你有一组纯粹的方法,你可以在没有任何实现知识的情况下调用。事实上,一些库如 JMS 和 JDBC 提供了没有任何实现的接口。

这种分离意味着您不需要知道任何实际实现的类。

于 2013-07-16T20:12:59.703 回答
5

接口允许您保证某些方法存在并返回所需的类型。当编译器知道这一点时,它可以使用该假设来处理未知类,就好像它们具有某些已知行为一样。例如,可比较接口保证实现类将能够 compareTo() 一些类似的对象并返回一个 int。

这意味着您可以比较实现此接口的任何内容 - 因此您可以对任何可比较的内容进行排序,而不是编写一个方法来排序字符串,另一个方法来排序整数,另一个方法来排序 LabelledBoxesOfBooks

于 2013-07-16T20:12:50.050 回答
2

接口本质上保证所有继承它的方法都有它的方法,这样你就可以安全地调用接口中的方法来继承它的任何东西。

于 2013-07-16T20:09:42.597 回答
0

它使使用接口定义 API 变得更加容易,因此接口的所有具体实现都在每个类中提供了预期的方法。

它还提供了一种实现多重继承的方法,这在 Java 中是不可能的(在 Java 中)使用直接的类继承。

于 2013-07-16T20:18:18.300 回答