Java 实现接口如何提供附加功能?
我理解接口是类的契约,如果类实现了接口,那么接口中的所有方法都必须在类中 下面是一个涉及此接口的示例,让我感到困惑:Java 实现接口如何提供附加功能?,java,Java,我理解接口是类的契约,如果类实现了接口,那么接口中的所有方法都必须在类中 下面是一个涉及此接口的示例,让我感到困惑: public class Contact implements Comparable<Contact> { private String name; public int compareTo(Contact other) { return name.compareTo(other.name); } } 但如果合同未执行类似
public class Contact implements Comparable<Contact> {
private String name;
public int compareTo(Contact other) {
return name.compareTo(other.name);
}
}
但如果合同
未执行类似的可比
:
public class Contact {
private String name;
public int compareTo(Contact other) {
return name.compareTo(other.name);
}
}
调用Collections.sort
将产生编译时错误,即使compareTo
方法仍然存在
显然,通过实现接口可以提供额外的功能。除了强制结构之外,接口的用途是什么?因为如果
联系人实现了可比较的
,那么联系人
就是可比较的
让我们看一看源代码,在ComparableTimSort.countRunAndMakeAscending()中有一行:
if (((Comparable) a[runHi++]).compareTo(a[lo]) < 0)
如果没有,那么我显然无法将实例分配给可比较的
类型,因此我不知道Contact
有什么方法(不诉诸反射)
通过实现Comparable
,我告诉编译器这个类是Comparable
,因此可以在需要时作为一个类来处理。必须实施这些方法只是其中的一个副作用
至于为什么它是编译时而不是运行时错误,您只需要查看方法集合的声明。排序
即可找到:
public static <T extends Comparable<? super T>> void sort(List<T> list)
publicstatic上面的答案是技术上的,但是从设计的角度来看,它们在程序层之间创建了一个抽象层。在设计复杂系统时,这一点很重要,因为它减少了类之间的依赖性,并允许更高的可维护性 其他答案给出了更常见的接口用法。我还有两个想法:
- 简单标记
Serializable
既不包含方法,也不包含常量,只需声明类的实例可以成功序列化为流并反序列化回来
- JDK代理。
代理
只能代理接口。因此,要代理一个类,必须首先将其公共方法导出到一个或多个接口。它通常用于Spring框架AOP
不,“强制结构”完全是接口的目的。(虽然在Java8中有一些变化…)接口是优秀的、非常灵活的设计工具。是关于打字的。Collections.sort的声明类似于sort(Collection@krems排序(Collection@BorisSpider我没有说完全是那样的,只是想让内容更容易理解。顺便说一句,sort函数不能将集合作为参数,因为不是每个集合都是有序的,事实上是集合。sort接受列表,实际签名在下面的答案中给出,如下所示:它不是@Se可序列化的
,因为这将是一个注释。事实上,可序列化的
的使用是JDK中最糟糕的设计决策之一,不应该作为初学者的示例。标记接口不应该作为注释使用。第二个示例是对非常复杂的运行时的大规模过度简化过程。@BoristheSpider:感谢您注意到无关的@
。我同意这是一个糟糕的设计,但它在JDK中,我花了相当长的时间才理解接口可以用作简单的标记(我自学了Java…).我也承认代理比我写的要复杂得多。我只想坚持使用Spring AOP需要使用接口的层分离这一事实。但你的答案比我的好得多:-)
final Comparable<Contact> contact = new Contact();
public static <T extends Comparable<? super T>> void sort(List<T> list)