这个答案与coolest_head的基本相同,只是更明确地传达了有用性。
正如coolest_head 所解释的,当您将来可能想要切换程序的可能子组件时,接口很有用。它们还允许您更轻松地分离程序结构各个部分的关注点,因为使用接口可以确保某些不相关的类等对程序的其他部分不可见。
例如,假设您要读取任意数据并打印出来,如下所示:
SomeReader someReader = new SomeReader();
String data = someReader.readLine();
System.out.println(data);
这里没什么特别的,对吧?但是,虽然这个示例很简单,但它已经与 SomeReader 类相关联,这意味着您对该类所做的所有更改都必须传播到您使用该类的类 - 特别是如果你重构一些内部部分!相反,你想这样做
IMyReader reader = new SomeReader();
System.out.println(reader.readLine());
你快到了 - 现在打印代码不再关心具体的实现,只关心接口公开的部分。这通常就足够了,因为现在您只需切换一个 new 语句,就可以获得新的实现以及仍然按预期工作的任何内容(只要实现类之间遵守接口的约定! )。当您最终多次使用该特定对象时,这特别方便 - 这里我只使用它一次,但实际上,如果您正在使用例如列表,您通常会执行多少次操作?
所以,要真正夸大这个例子,你的代码最终可能会是这样的
public class RowPrinter {
private final IMyReader reader;
public RowPrinter(IMyReader reader) {
this.reader = reader;
}
public void print() {
IMyReader reader = getReader();
System.out.println(reader.readLine());
}
protected IMyReader getReader() {
return reader;
}
}
注意到构造函数的那部分了吗?那是inversion of control,让我告诉你,这是一个很酷的软件工程。我可以根据经验说话,它可以帮助您解决很多麻烦,无论是从数据库产品切换到另一个产品还是使代码的某些部分线程安全。或者,也许您只是想为某个类添加一层日志记录,可以通过包装 decorator 轻松实现,它恰好实现了与包装类相同的接口。而这仅仅是个开始。
接口带来了很多好处,这些好处通常从简单的例子中看不出来,尽管简单的例子确实能让你顺利进行。尽管 Java 中的接口是一种语言结构,但它们实际上更像是一种编程范式,而不仅仅是一种语言的特性,在某些语言中,如果您找到正确的方法,模拟接口确实是有益的。