Java 8默认方法与抽象类中的非抽象方法

Java 8接口默认方法与抽象类中的非抽象方法 – 两者之间是否存在任何差异(除了iface的差异 – 类,可见性等)

不是Java中的默认方法,这意味着它违背了Java多年来所宣传的本质?!

抽象类中的非抽象方法将在具体子类调用super()时被调用(如果被覆盖)。 所以有多种可能性。 如果不覆盖方法,则将执行超类方法。 如果我们在具体的子类方法中使用super(),那么将执行带有超类方法的重写方法。

其中Java 8接口的默认方法完全不同。 它为开发人员提供了在实现类中实现该方法的选择。 如果该函数未实现,则只执行默认方法。

可能的用例:

JDK库中这个新特性最重要的用例是可以在不破坏现有实现的情况下扩展现有接口:向接口添加新的抽象方法将需要所有实现类来实现该新方法。( 来源 )

要记住的重要一点是,默认方法不能访问状态,只能访问行为。 它实际上是定义合理的默认行为的好地方。

想象一下你有一个界面:

 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); } 

这是一个简单的示例,但显示了默认方法如何有用。 在这种情况下, growSlowgrowFast行为的方式是接口契约的一部分,因此在接口级别定义它们的行为是有意义的。

然而,界面没有假设如何实施“种植植物”的行动。 这可以在抽象类中定义。

首先,默认方法允许您在不破坏现有实现的情况下向接口添加新方法

还以Collections类为例,它是Collection接口权限的实用程序类。

因此,使用默认方法,我们现在可以将所有实用程序方法作为默认实现移动到Collection本身,这比为这些实用程序创建单独的类更有意义。

此外,您还可以从多个接口inheritance方法,这些方法无法使用普通的abstract类来完成。

最大的区别是构造函数可能在匿名类中运行,可能带有已检查的exception。 这可以防止匿名类成为function接口,从而使它们不能用作lambda表达式的基础。

主要区别在于:Java 8默认接口方法是公共的,而抽象类的非抽象(具体)方法可以定义为public,protected或private。 Lambda表达式在Java 8中引入,要使用lambda特性我们需要默认方法(以保持向后兼容性),抽象类的非抽象方法无法达到目的。