Java 8接口默认方法与抽象类中的非抽象方法 - 两者之间是否有任何差异(除了iface的差异,可见性等)。
这不是Java中的默认方法,这意味着它违背了Java多年来宣传的本质吗?!
答案 0 :(得分:7)
抽象类中的非抽象方法将在具体子类调用super()时被调用(如果被覆盖)。所以有多种可能性。如果未覆盖方法,则将执行超类方法。如果我们在具体的子类方法中使用super(),那么将执行带有超类方法的重写方法。
其中Java 8接口的默认方法完全不同。它为开发人员提供了在实现类中实现该方法的选择。如果该功能未实现然后只有,则将执行默认方法。
可能的用例:
JDK库中这个新功能最重要的用例是可以在不破坏现有实现的情况下扩展现有接口:向接口添加新的抽象方法将需要所有实现类来实现该新方法。({{ 3}})
答案 1 :(得分:4)
要记住的重要一点是,默认方法不能访问状态,只能访问行为。它实际上是定义合理的默认行为的好地方。
想象一下,你有一个界面:
public interface Plant {
enum Pace { FAST, SLOW; }
void grow(Pace pace);
void growFast();
void growSlow();
}
提供默认行为似乎是合理的:
default void growFast() { grow(Pace.FAST); }
default void growSlow() { grow(Pace.SLOW); }
这是一个简单的示例,但展示了默认方法如何有用。在这种情况下,growSlow
或growFast
的行为方式是接口契约的一部分,因此在接口级定义它们的行为是有意义的。
然而,界面没有假设如何实施“种植植物”的行动。这可以在抽象类中定义。
答案 2 :(得分:0)
首先,默认方法允许您向接口添加新方法,而不会破坏现有的实现。
还以Collections
类为例,它是Collection
接口权限的实用程序类。
因此,使用默认方法,我们现在可以将所有实用程序方法作为默认实现移动到Collection
本身,这比为这些实用程序创建单独的类更有意义。
此外,您将能够从多个接口继承方法,而这些方法无法使用普通的abstract
类完成。
答案 3 :(得分:0)
最大的区别是构造函数可能在匿名类中运行,可能带有已检查的异常。这可以防止匿名类成为函数接口,从而使它们不能用作lambda表达式的基础。
答案 4 :(得分:0)
主要区别是: Java 8默认接口方法是公共的,而抽象类的非抽象(具体)方法可以定义为public,protected或private。 Lambda表达式在Java 8中引入,要使用lambda特性我们需要默认方法(以保持向后兼容性),抽象类的非抽象方法不能达到目的。