Java 8:虚拟扩展方法与抽象类

我正在研究Java 8接口中的新虚拟扩展方法:

public interface MyInterface { default String myMethod() { return "myImplementation"; } } 

我的目的是允许接口随着时间的推移而发展,以及多重inheritance位,但它们看起来非常类似于我的抽象类。

如果你正在做新工作,那么抽象类优先于扩展方法来为“接口”提供实现,还是这两种方法在概念上是等价的?

这种结构的一个主要目的是保持向后兼容性。 在Java语言中添加闭包是一个很大的改动,需要更新一些内容才能充分利用这一点。 例如,Java 8中的Collection将具有诸如forEach()方法,这些方法与lambdas一起使用。 简单地将这些方法添加到预先存在的Collection接口是不可行的,因为它会破坏向后兼容性。 我在Java 7中编写的实现Collection将不再编译,因为它缺少这些方法。 因此,这些方法是通过“默认”实现引入的。 如果您了解Scala,您会发现Java interface变得更像Scala trait

至于接口与抽象类,这两者在Java 8中仍然不同 ; 例如,您仍然无法在界面中拥有构造函数。 因此,这两种方法本身并不是“概念上等同的”。 抽象类更结构化,可以具有与之关联的状态,而接口则不能。 您应该在程序的上下文中使用更有意义的内容,就像在Java 7及更低版本中一样。

抽象类包含状态 (实例字段),以便提供一些常见的行为(方法)。
你通常不会(永远?)看到没有状态的抽象类。

接口指定function 。 它们旨在将行为声明为合同,而不是实现它。
因此,任何指定为接口一部分的方法都是“辅助”方法 – 它们不会影响实现。

  1. 抽象类不能是lambda表达式的根类,而具有虚扩展方法的接口可以是。
  2. 抽象类可以有构造函数和成员变量,而接口则不能。 我相信它是一个可能的构造函数的执行,并且可能抛出一个禁止抽象类成为lambda表达式的根的已检查exception。

如果要编写允许用户使用lambda表达式的API,则应使用接口。

抽象类在以下区域的java-8接口上得分。

  1. 使用抽象类,您可以声明非静态和最终的字段,并定义public,protected和private具体方法使用接口,所有字段都自动为public,static和final,并且您声明或定义的所有方法(作为默认方法)都是公共的

  2. 与具有常量的接口不同,可以使用子类共享/修改可变状态

  3. 抽象类可用于实现Template_method_pattern :它定义操作中算法的程序框架,将一些步骤推迟到子类。
  4. Abstract类可用于实现Decorator_pattern :一种设计模式,允许将行为者静态或动态地添加到单个对象,而不会影响同一类中其他对象的行为。

抽象类和函数接口之间的区别很多,就像普通接口和抽象类之间的差异一样,但测量差异是我们可以在函数接口中使用默认方法但不能在抽象类中使用默认方法,这会改变并帮助java 8中的所有集合实现()和其他使用lambda的性能方法

 package com.akhi; public abstract class AbstractDemo { abstract void letsRun(); // abstract valid public String toString(); // invalid but valid in interface or functional interface public boolean equals(Object o); // invalid but valid in interface or functional interface public int concrete() { // Concrete is invalid in interface return 1; } public default int getMult(int a, int b) // default invalid but valid in case of functional { return a * b; } public static int getSum(int a, int b) // static allowed { return a + b; } }