Java8:虚拟扩展方法与抽象类
我正在研究Java 8接口中的新虚拟扩展方法:Java8:虚拟扩展方法与抽象类,java,interface,java-8,abstract-class,Java,Interface,Java 8,Abstract Class,我正在研究Java 8接口中的新虚拟扩展方法: public interface MyInterface { default String myMethod() { return "myImplementation"; } } 我理解它们的目的是允许一个接口随着时间的推移而发展,以及多重继承位,但它们在我看来非常像一个抽象类 如果您正在做新的工作,那么抽象类是否比扩展方法更倾向于为“接口”提供实现,或者这两种方法在概念上是等价的 抽象类不能是lambda表达式的根类
public interface MyInterface {
default String myMethod() {
return "myImplementation";
}
}
我理解它们的目的是允许一个接口随着时间的推移而发展,以及多重继承位,但它们在我看来非常像一个抽象类
如果您正在做新的工作,那么抽象类是否比扩展方法更倾向于为“接口”提供实现,或者这两种方法在概念上是等价的
如果您想编写一个允许用户使用lambda表达式的API,那么应该改用接口。这种构造的一个主要目的是保持向后兼容性。将闭包添加到Java语言中是一个相当大的变化,需要进行更新以充分利用这一点。例如,在Java 8中,将有一些方法,如
forEach()
,它们与lambdas一起工作。简单地将这些方法添加到预先存在的集合
接口是不可行的,因为它会破坏向后兼容性。我用Java 7编写的实现集合的类将不再编译,因为它缺少这些方法。因此,这些方法是通过“默认”实现引入的。如果您了解Scala,您可以看到Javainterface
s越来越像Scalatrait
s
至于接口和抽象类,在Java8中两者仍然不同;例如,在接口中仍然不能有构造函数。因此,这两种方法本身并不“概念上等同”。抽象类的结构更为结构化,可以具有与之关联的状态,而接口则不能。您应该在程序上下文中使用更有意义的选项,就像在Java 7及以下版本中一样。抽象类保存状态(实例字段),以便提供一些常见行为(方法)。
您通常(从未)看到没有状态的抽象类
接口指定功能。它们旨在将行为声明为合同,而不是实施合同。
因此,任何被指定为接口一部分的方法都是“助手”方法——它们不会影响实现。在下面的区域对java-8
接口进行评分
使用抽象类,您可以声明非静态和最终的字段,并定义公共、受保护和私有的具体方法。对于接口,所有字段都自动为公共、静态和最终字段,并且您声明或定义的所有方法(作为默认方法)都是公共的
可变状态可以与子类共享/修改,不像接口只有常量
抽象类可用于实现:它定义操作中算法的程序框架,将某些步骤推迟到子类
抽象类可用于实现:一种设计模式,允许将behaviuor静态或动态添加到单个对象,而不影响同一类中其他对象的行为
抽象类和函数接口之间的差异就像普通接口和抽象类之间的所有差异一样,但度量差异是有限的
我们可以在函数接口中使用默认方法,但不能在抽象类中使用默认方法,这改变了java 8 foreach()中的所有集合实现,并使用lambda帮助实现了其他性能方法
-行为继承与状态继承之间的区别是至关重要的。这基本上明确了它们的目的。它们的主要目的是实现与针对Java 7编译的代码的向后兼容性,并且不会实现添加到Java 8中的任何“函数”方法。Java.util.AbstractCollection
?抽象类没有状态是正常的。从Java SE 8来看,抽象类可以具有实例状态,而与实现的接口不能具有实例状态,这只是语言上的一个奇怪现象。@TomHawtin tackline:但如果您查看AbstractCollection
的文档,它会说,“此类提供了集合
接口的框架实现,以最小化实现此接口所需的工作量。“换句话说,它只是一个方便的功能,但不需要出于任何特定的设计原因。相比之下,Collection
是编写适用于所有集合的通用代码所必需的。我认为这与此无关。抽象类通常不持有状态,这是事实。在JavaSE8中,我相信Collection
将包含一些“Collection
接口的框架实现”@TomHawtin-tackline:“抽象类通常不保持状态,这是真的。”。。。你介意给其他此类课程命名吗?
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;
}
}