在Java中,明确何时使用接口的一个好例子将是理想的,并且适用的任何特定规定。
在Java中,明确何时使用接口的一个好例子将是理想的,并且适用的任何特定规定。
一个好的查看位置是集合框架。
java.util.List //interface
java.util.ArrayList //Concrete class
java.util.LinkedList //Concrete class
你可以编写这样的代码:
List l = new ArrayList();
l.add(..)
//do something else.
如果在将来您想要使用LinkedList
或者自己的实现了List接口的AwesomeList
来更改此实现,您只需要更改第一行为:
List l = new MyAwesomeList();
or
List l = new LinkedList();
其余的代码将会继续执行。javax.sql
的实现,但几乎从不使用实现连接池的库,通常只需要一个 Driver
实现。现在真的有必要拥有 Statement
和 PreparedStatement
吗?也许可以通过使用泛型来减少 getXX()
和 updateXXX()
方法的数量,从而更好地设计 ResultSet
接口... - Janez Kuhar接口在程序中的使用通常是为了应对变化,即在设计中需要弯曲的地方以及预期发生变化的地方。
实现本身具有脆弱性:很容易出故障。这就是为什么子类化并不总是最佳解决方案,长而复杂的方法也一般不是好主意,因为它们会在自身实现某些复杂行为时产生问题。
接口比实现更加灵活,可以处理程序设计上更多的压力。
通过在程序中引入接口,您可以在接口的变化点插入不同的实现,从而引入了程序的变化点。接口的主要目的是抽象,“做什么”和“怎么做”分离。
为了安全地使用接口,有一个重要的规则需要牢记,那就是Liskov替换原则 [UncleBob, Wikipedia]。虽然像Java这样的语言编译器会确保语法正确(正确的参数数量、类型等),LSP涉及到语义。简而言之,LSP要求接口的每个实现都必须(也)正确地表现自己,以便真正可替代如上所述。
来自 Oracle 文档 page
如果满足以下条件,请考虑使用接口:
- 您希望不相关的类实现您的接口。例如,许多不相关的对象可以实现 Serializable 接口。
- 您想指定特定数据类型的行为,但不关心谁实现其行为。
- 您想利用类型的多重继承。
查看与代码示例相关的 SE 问题,并已有良好答案。
当您需要多个实现相同行为时,可以使用接口。这是一个接口的示例,对象可以实现它来显示它们都可以被序列化为XML。
public interface Xmlizable
{
public String toXML();
}
那么你可以将“Xmlizable”接口传递到只关心该接口的方法中。
toXML
。 - Tom Hawtin - tacklineSomeReader 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;
}
}
因此,Collection是一个具有List(有序)和Set(无序)子接口的接口。现在有许多关于列表的问题,它应该同步/还是不同步,它应该是链表还是不是等等。每个“行为”都将有自己的接口/抽象类。
当您想要在集合中指定“某些”行为时,就需要抽象类。例如,所有集合(集合/列表等)都可以具有“toString”表示,这仅需要遍历元素(有序/无序)并将它们字符串化。该行为可以存在于“AbstractCollection”等中。
如果您遵循JDK集合的层次结构,则学习接口和抽象类的绝佳场所:)
远程通信中的接口:
接口还可以用于定义在系统不同部分之间进行通信的“协议”,可能通过远程调用实现。因此,接口仅定义了可以调用什么、使用哪些参数以及调用后会返回什么内容。客户端使用接口,服务器实现具体的实际代码。
附注:
在Java中,您只能从一个类继承(扩展),但是您可以实现多个接口,因此有时需要在需要多重继承的情况下使用接口,并且当您决定不使用组合而选择继承时也需要使用接口。