Java 8允许在称为default methods的接口中默认实现方法。
我在什么时候使用那种接口默认方法,而不是抽象类(带有抽象方法)之间感到困惑。
那么什么时候应该使用默认方法的接口,什么时候应该使用抽象类(带有抽象方法)?抽象类在这种情况下仍然有用吗?
Java 8允许在称为default methods的接口中默认实现方法。
我在什么时候使用那种接口默认方法,而不是抽象类(带有抽象方法)之间感到困惑。
那么什么时候应该使用默认方法的接口,什么时候应该使用抽象类(带有抽象方法)?抽象类在这种情况下仍然有用吗?
当前回答
这两个是完全不同的:
默认方法是在不改变现有类状态的情况下向其添加外部功能。
抽象类是一种普通的继承类型,它们是用于扩展的普通类。
其他回答
这两个是完全不同的:
默认方法是在不改变现有类状态的情况下向其添加外部功能。
抽象类是一种普通的继承类型,它们是用于扩展的普通类。
本文将对此进行描述。想想forEach of Collections。
List<?> list = …
list.forEach(…);
The forEach isn’t declared by java.util.List nor the java.util.Collection interface yet. One obvious solution would be to just add the new method to the existing interface and provide the implementation where required in the JDK. However, once published, it is impossible to add methods to an interface without breaking the existing implementation. The benefit that default methods bring is that now it’s possible to add a new default method to the interface and it doesn’t break the implementations.
正如在其他回答中提到的,添加实现到接口的能力是为了在Collections框架中提供向后兼容性。我认为,提供向后兼容性可能是向接口添加实现的唯一好的理由。
否则,如果您将实现添加到接口,那么您就违反了最初添加接口的基本规律。Java是一种单一继承语言,不像c++允许多重继承。接口提供了支持多重继承的语言所具有的类型优势,而不会引入多重继承所带来的问题。
更具体地说,Java只允许实现的单一继承,但它允许接口的多重继承。例如,以下是有效的Java代码:
class MyObject extends String implements Runnable, Comparable { ... }
MyObject只继承了一个实现,但它继承了三个契约。
Java传递了实现的多重继承,因为实现的多重继承带来了许多棘手的问题,这些问题超出了本文的讨论范围。添加接口是为了允许合约的多重继承(又名接口),而不存在实现的多重继承问题。
为了支持我的观点,这里引用了Ken Arnold和James Gosling在《Java编程语言》(第4版)一书中的一句话:
Single inheritance precludes some useful and correct designs. The problems of multiple inheritance arise from multiple inheritance of implementation, but in many cases multiple inheritance is used to inherit a number of abstract contracts and perhaps one concrete implementation. Providing a means to inherit an abstract contract without inheriting an implementation allows the typing benefits of multiple inheritance without the problems of multiple implementation inheritance. The inheritance of an abstract contract is termed interface inheritance. The Java programming language supports interface inheritance by allowing you to declare an interface type
请首先考虑开/闭原则。接口中的默认方法确实违反了它。这是Java中的一个不好的特性。它助长了糟糕的设计、糟糕的架构和低软件质量。我建议完全避免使用默认方法。
问自己几个问题: 为什么不能把方法放到抽象类中?那么您是否需要多个抽象类呢?然后想想你的类负责什么。您确定要放入单个类中的所有方法都实现了相同的目的吗?可能你会区分几个目的,然后将你的类分成几个类,每个目的有自己的类。
Remi Forax规则是不要用抽象类进行设计。你用界面来设计你的应用。无论Java的版本是什么,无论语言是什么。它以SOLID原理中的界面分离原理为依据。
稍后您可以使用抽象类来分解代码。现在有了Java 8,你可以直接在界面中完成。这只是个设施,仅此而已。