我正在研究Java 8接口中的新虚拟扩展方法:
public interface MyInterface {
default String myMethod() {
return "myImplementation";
}
}
我明白他们允许接口随时间演变的目的,以及多重继承的部分,但它们看起来对我来说非常像抽象类。
如果要进行新的工作,在提供“接口”的实现方面,是优先选择抽象类还是扩展方法?这两种方法在概念上是否相等?
我正在研究Java 8接口中的新虚拟扩展方法:
public interface MyInterface {
default String myMethod() {
return "myImplementation";
}
}
我明白他们允许接口随时间演变的目的,以及多重继承的部分,但它们看起来对我来说非常像抽象类。
如果要进行新的工作,在提供“接口”的实现方面,是优先选择抽象类还是扩展方法?这两种方法在概念上是否相等?
这样的构造的一个主要目的是保留向后兼容性。Java语言添加闭包是相当重大的改变,需要更新才能充分利用它的优势。例如,Java 8中的 Collection
将有诸如 forEach()
这样的方法,与lambda一起使用。简单地将此类方法添加到现有的 Collection
接口中是不可行的,因为它会破坏向后兼容性。我在Java 7中编写的实现Collection
的类将不再编译,因为它缺少这些方法。因此,这些方法被引入了“默认”实现。如果您了解Scala,您会发现Java的 interface
变得更像Scala的 trait
s。
关于接口和抽象类,它们在Java 8中仍然是不同的。例如,在接口中仍然不能有构造函数。因此,从本质上讲,这两种方法并不“概念上等价”。抽象类更加有结构化,并且可以与状态相关联,而接口则不能。您应该根据程序的上下文选择使用哪种方法,就像在Java 7及以下版本中一样。
如果您想编写一个允许用户使用lambda表达式的API,应该使用接口。
抽象类具有状态(实例字段),以提供一些通用行为(方法)。
通常情况下,您不会看到没有状态的抽象类。
接口规定功能。它们旨在将行为声明为合同,而不是实现它。
因此,作为接口的一部分指定的任何方法都是“帮助器”方法--它们不影响实现。
java.util.AbstractCollection
?抽象类没有状态是很正常的。从Java SE 8开始,抽象类可以拥有实例状态,而带有实现的接口则不能,这只是一种语言上的怪异现象。 - Tom Hawtin - tacklineAbstractCollection
的文档,它说:“此类提供了Collection
接口的骨架实现,以最小化实现此接口所需的工作量。”换句话说,这只是一个方便功能,但它不需要出于任何特定的设计原因。相比之下,编写适用于所有集合的通用代码是必须的,因此Collection
是必要的。 - user541686抽象类和函数式接口之间的区别很多,就像普通接口和抽象类之间的所有区别一样,但最重要的区别是我们可以在函数式接口中拥有默认方法,而在抽象类中则不行。这种变化帮助了Java 8中所有集合实现,在使用lambda表达式的foreach()和其他性能方法时产生了改变。
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;
}
}
抽象类 在以下方面优于 java-8
接口。
使用抽象类,您可以声明非静态和final字段,并定义公共、受保护和私有的具体方法。使用接口,所有字段都自动为public、static和final,并且您声明或定义的所有方法(作为默认方法)都是public的
可变状态可以与子类共享/修改,而接口只有常量