关于Java:将对象声明为接口有什么好处?

What are the benefits of declaring an object as interface?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
What does it mean to “program to an interface”?

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

例如:

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

或者你也可以

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

避免进口java.util.Map

与类本身(上面第二个)相比,通过接口(上面第一个)声明它有什么好处?

谢谢


因为它不是API的一部分,所以它是实现细节。最好在实现中具体化,这里没有必要抽象化。

我的答案

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


Map这样的接口声明对象可以做什么。另一方面,像HashMap这样的类定义对象如何执行接口声明的操作。

如果您声明一个变量(或字段,或其他任何变量)Map,则说明您的代码只依赖于该接口定义的契约,而不依赖于实现的具体情况。

如果您声明它是一个HashMap,那么应该理解您需要一个特定版本的地图(无论出于什么原因),并且不能用其他东西替换它。

我倾向于不喜欢常见的答案,比如"因为你可以改变实现",简单地说,经过多年的实践,你会发现它不会像那样频繁发生,而且主要的好处是你的意图的微妙(但清晰)的表达。


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

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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.printstomething(…),则传递fileprinter或screenprinter实例并不重要,因为该方法不关心。它知道对象实现了接口打印机,也实现了它的方法。

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


如果使用Map someMap,则设计的是接口而不是实现。因此,您可以轻松地在其他实现之间切换。

所以,你的Map可以指向HashMapLinkedHashMap或任何其他物体,它是Map的一个子类。

所以,如果你有:

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

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

1
someMap = new LinkedHashMap<>();

但是,如果在lhs上使用HashMap,则只能指向HashMap类型的对象。

但是,这样在性能上没有区别。但建议始终将design改为interface而不是implementation


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