Java 8: virtual extension methods vs abstract class
我正在研究Java 8接口中的新虚拟扩展方法:
1 2 3 4 5
| public interface MyInterface {
default String myMethod () {
return"myImplementation";
}
} |
我的目的是让一个接口随着时间和多重继承位而发展,但是在我看来它们非常像一个抽象类。
如果您正在做新的工作,抽象类比扩展方法更倾向于为"接口"提供实现,或者这两种方法在概念上是等效的?
- lambdafaq.org/…—行为继承与国家继承之间的区别至关重要。
- 什么是default方法?这很清楚地说明了他们的目的。它们的主要目的是实现与Java 7编译的代码的向后兼容性,并且不会实现添加到Java 8中的任何"功能"方法。
这种构造的一个主要目的是保持向后兼容性。将闭包添加到Java语言是一个很大的改变,需要更新这些内容来充分利用这一点。例如,在Java 8中,EDCOX1 0的方法将具有EDCOX1、1、和LAMBDAS协同工作的方法。简单地将这些方法添加到现有的Collection接口是不可行的,因为它会破坏向后兼容性。我在Java 7中实现的一个类实现EDCOX1,0,将不再编译,因为它将缺少这些方法。因此,这些方法是通过"默认"实现引入的。如果你知道斯卡拉,你可以看到Java EDCOX1的4个s变得越来越像Scala EDCOX1,5个s。
至于接口和抽象类,这两个在Java 8中仍然是不同的,例如,在接口中仍然不能有构造函数。因此,这两种方法本身并不是"概念上等价的"。抽象类更具结构性,并且可以具有与其关联的状态,而接口则不能。在程序的上下文中使用任何更为合理的内容,就像在Java 7和下面所做的那样。
抽象类保持状态(实例字段),以便提供一些常见的行为(方法)。你通常(曾经)不会?请参见没有状态的抽象类。
接口指定功能。他们的目的是将行为声明为一个契约,而不是实现它。因此,任何被指定为接口一部分的方法都是"helper"方法——它们不会影响实现。
- EDOCX1?0?抽象类没有状态是正常的。从Java SE 8,抽象类可以具有实例状态和与实现接口的事实不能仅仅是语言怪异。
- @tomhawtin tackine:但是如果您查看AbstractCollection的文档,它会说,"这个类提供了Collection接口的框架实现,以最小化实现该接口所需的工作量。"换句话说,它只是一个方便的特性,但由于任何特定的设计原因,它不需要出现在那里。相比之下,Collection对于编写适用于所有集合的通用代码是必需的。
- 我不认为这有什么关系。的确,抽象类通常不保持状态。在Java SE 8中,我相信EDCOX1(2)将包含一些"EDOCX1×2接口"的"骨架实现"。
- @Tomhawtin Talkine:"抽象类通常不保存状态是正确的。"你介意给其他的类命名吗?
抽象类不能是lambda表达式的根类,而具有虚拟扩展方法的接口可以是。
抽象类可以有构造函数和成员变量,而接口不能。我相信它执行了一个可能的构造函数,并且可能抛出了一个检查过的异常,该异常禁止抽象类成为lambda表达式的根。
如果您想编写一个允许用户使用lambda表达式的API,那么应该使用接口。
抽象类和函数接口之间的差异与普通接口和抽象类之间的差异非常相似,但度量差异是我们可以在函数接口中使用默认方法,但不能在抽象类中使用默认方法,这将改变和帮助使用Java 8中的所有集合实现和使用lambda的其他性能方法。
ZZU1〔0〕
抽象类对下面区域中的java-8接口的得分。
使用抽象类,可以声明非静态和最终的字段,并定义公共、受保护和私有的具体方法。通过接口,所有字段都自动是公共的、静态的和最终的,并且您声明或定义的所有方法(作为默认方法)都是公共的。
与只有常量的接口不同,可变状态可以与子类共享/修改。
抽象类可用于实现模板方法模式:它在操作中定义算法的程序框架,将一些步骤延迟到子类。
抽象类可用于实现decorator_模式:一种设计模式,允许将behavior静态或动态地添加到单个对象中,而不影响同一类中其他对象的行为。