我正在研究Java 8接口中的新虚拟扩展方法:
public interface MyInterface {
default String myMethod() {
return "myImplementation";
}
}
我的目的是允许接口随着时间的推移而发展,以及多重继承位,但它们看起来非常像我的抽象类。
如果您正在开展新工作,抽象类是否优先考虑扩展方法以向“接口”提供实现,或者这两种方法在概念上是否相同?
答案 0 :(得分:31)
此类构造的一个主要目的是保持向后兼容性。为Java语言添加闭包是一个很大的改动,需要更新一些内容才能充分利用这一点。例如,Java 8中的Collection
将具有forEach()
等与lambdas结合使用的方法。简单地将这些方法添加到预先存在的Collection
接口是不可行的,因为它会破坏向后兼容性。我在Java 7中编写的实现Collection
的类将不再编译,因为它缺少这些方法。因此,这些方法是通过“默认”实现引入的。如果您了解Scala,您会发现Java interface
变得更像Scala trait
。
对于接口与抽象类,这两者在Java 8中仍然是不同的;例如,您仍然无法在界面中拥有构造函数。因此,这两种方法本身并不是“概念上等同的”。抽象类更结构化,可以具有与之关联的状态,而接口则不能。你应该在程序的上下文中使用更有意义的东西,就像在Java 7及以下版本中那样。
答案 1 :(得分:5)
如果要编写允许用户使用lambda表达式的API,则应使用接口。
答案 2 :(得分:5)
抽象类保持状态(实例字段),以提供一些常见的行为(方法)。
你通常不会(永远?)看到没有状态的抽象类。
接口指定功能。它们意味着将行为宣布为合同,而不是实施合同 因此,任何指定为接口一部分的方法都是“辅助”方法 - 它们不会影响实现。
答案 3 :(得分:0)
Abstract classes在以下区域的java-8
接口上得分。
使用抽象类,您可以声明 不是静态和最终的字段,并定义公共,受保护和私有的具体方法 。 使用接口,所有字段都自动为public,static和final,并且您声明或定义的所有方法(作为默认方法)都是公共的
可变状态 可以与子类共享/修改,而不像只有常量的接口
答案 4 :(得分:0)
抽象类和功能接口之间的差异与普通接口和抽象类之间的差异非常相似,但度量上的差异是
我们可以在函数接口中使用默认方法,但不能在抽象类中使用默认方法,这可以更改并帮助使用lambda帮助Java 8 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;
}
}
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;
}
}