7

可能重复:
“编程到接口”是什么意思?

我注意到有些人喜欢将一个对象声明为它实现的接口之一,即使在变量的范围内,没有必要将其视为接口,例如,没有期望接口的外部 API。

例如:

Map<String, Object> someMap = new HashMap<String, Object>();

或者你可以做

HashMap<String, Object> someMap = new HashMap<String, Object>();

并完全避免进口java.util.Map

通过接口(上面第一个)而不是类本身(上面第二个)声明它有什么优点?

谢谢

4

5 回答 5

3

诸如声明对象可以做什么接口。另一方面,诸如定义对象如何执行接口声明的操作的类。Map<A, B>HashMap<A, B>

如果您声明一个变量(或字段,或其他) a Map<A, B>,则说明您的代码仅依赖于该接口定义的合同,它不依赖于实现的细节。

如果您将其声明为 a HashMap<A, B>,则可以理解为您需要该特定版本的地图(无论出于何种原因),并且不能用其他东西替换它。

我倾向于不喜欢诸如“因为您可以更改实现”之类的常见答案,这仅仅是因为,经过多年的实践,您会发现它不会像那样频繁地发生,而且主要的好处确实如此微妙(但是明确)表达你的意图。

于 2012-10-09T18:00:05.733 回答
3

由于它不是 API 的一部分,因此它是实现细节。最好是具体的实现,这里没有抽象的意义。

我的上一个答案

在java中使用接口或类型定义变量?

于 2012-10-09T18:02:48.520 回答
1

如果以后不使用该变量,则没有优势/劣势。使用接口而不是对象的原因是为了提供更大的灵活性,但如果不使用该变量,则与性能方面没有区别。

于 2012-10-09T18:01:41.097 回答
1

如果您使用Map<String, Object> someMap,则您正在设计一个接口而不是实现..因此您可以轻松地在其他实现之间切换..

因此,您Map可以指向HashMapLinkedHashMap或任何其他对象,即 . 的子类Map

所以,如果你有: -

Map<String, Integer> someMap = new HashMap<>();

您可以稍后(如果需要)更改实现以指向LinkedHashMap:-

someMap = new LinkedHashMap<>();

而如果你HashMap在 LHS 上使用,你只能让它指向一个HashMap..类型的对象。

但是,因此在性能上没有区别..但建议始终design使用interface而不是implementation..

于 2012-10-09T18:02:04.060 回答
1

接口定义了类必须实现的方法。这样——如果你想调用一个接口定义的方法——你不需要知道一个对象的确切类类型,你只需要知道它实现了一个特定的接口。

例子:

interface Printer {
    public void print(String text);
}

class FilePrinter implements Printer {
    public void print(String text) {
       //append the text to a file
    }
}

class ScreenPrinter implements Printer {
    public void print(String text) {
       //write the text on the screen
    }
}

class SomeClass {
    public printSomething(Printer myPrinter) {
        myPrinter.print("Hello");
    }
}

如果您调用 SomeClass.printSomething(...),则传递 FilePrinter 或 ScreenPrinter 的实例并不重要,因为该方法并不关心。它知道对象实现了接口 Printer 并实现了它的方法。

关于接口的另一个重要点是一个类可以实现多个接口。

于 2012-10-09T18:02:53.953 回答