Rav*_*avi 80 java default interface java-8
Java中的接口类似于类,但接口的主体只能包含抽象方法和
final字段(常量).
最近,我看到了一个问题,看起来像这样
interface AnInterface {
public default void myMethod() {
System.out.println("D");
}
}
Run Code Online (Sandbox Code Playgroud)
根据接口定义,只允许抽象方法.为什么它允许我编译上面的代码?什么是default关键字?
另一方面,当我试图写下面的代码时,它说 modifier default not allowed here
default class MyClass{
}
Run Code Online (Sandbox Code Playgroud)
代替
class MyClass {
}
Run Code Online (Sandbox Code Playgroud)
谁能告诉我default关键字的目的?是否只允许在界面内?它与default(无访问修饰符)有何不同?
Ell*_*sch 61
这是Java 8中的一个新功能,它允许interface提供实现.在Java 8 JLS-13.5.6中描述.读取的接口方法声明(部分)
添加
default方法,或从一个改变方法abstract,以default不破坏兼容性与预先存在的二进制文件,但可能会导致IncompatibleClassChangeError如果一个预先存在的二进制尝试调用的方法.如果符合条件的类型,出现此错误T,是的两个接口的子类型,I并且J,其中两个I和J声明一个default具有相同签名和结果的方法,既不I也不J是另一个的子接口.
JDK 8中的新功能(部分)
默认方法允许将新功能添加到库的接口,并确保与为这些接口的旧版本编写的代码的二进制兼容性.
spr*_*ter 21
Java 8中添加了默认方法,主要是为了支持lambda表达式.设计师(巧妙地,在我看来)决定使用lambdas语法来创建接口的匿名实现.但鉴于lambdas只能实现单一方法,它们将限制为使用单一方法的接口,这将是一个非常严格的限制.相反,添加了默认方法以允许使用更复杂的接口.
如果你需要对default由于lambdas引入的声明有所说服,请注意,Mark Reinhold在2009年提出的关于Project Lambda的许多提议,提到"扩展方法"作为强制性功能添加到支持lambdas.
这是一个展示这个概念的例子:
interface Operator {
int operate(int n);
default int inverse(int n) {
return -operate(n);
}
}
public int applyInverse(int n, Operator operator) {
return operator.inverse(n);
}
applyInverse(3, n -> n * n + 7);
Run Code Online (Sandbox Code Playgroud)
非常做作我意识到但应该说明如何default支持lambdas.因为inverse是默认值,所以如果需要,可以通过实现类轻松覆盖它.
Sau*_*aur 14
Java 8中引入了一个称为默认方法的新概念.默认方法是具有一些默认实现的方法,有助于在不破坏现有代码的情况下改进接口.让我们看一个例子:
public interface SimpleInterface {
public void doSomeWork();
//A default method in the interface created using "default" keyword
default public void doSomeOtherWork(){
System.out.println("DoSomeOtherWork implementation in the interface");
}
}
class SimpleInterfaceImpl implements SimpleInterface{
@Override
public void doSomeWork() {
System.out.println("Do Some Work implementation in the class");
}
/*
* Not required to override to provide an implementation
* for doSomeOtherWork.
*/
public static void main(String[] args) {
SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl();
simpObj.doSomeWork();
simpObj.doSomeOtherWork();
}
}
Run Code Online (Sandbox Code Playgroud)
输出是:
Do Some
在接口中的DoSomeOtherWork 类实现中实现
Mak*_*oto 10
在其他答案中忽略的一点是它在注释中的作用.早在Java 1.5之前,该default关键字就是为注释字段提供默认值的一种方法.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Processor {
String value() default "AMD";
}
Run Code Online (Sandbox Code Playgroud)
随着Java 8的引入,它的使用过载,允许用户在接口中定义默认方法.
其他被忽略的东西:声明default class MyClass {}无效的原因是由于类的声明方式.该语言中没有允许该关键字出现在那里的规定.但它确实出现在接口方法声明中.
小智 5
接口中的默认方法允许我们在不破坏旧代码的情况下添加新功能。
在 Java 8 之前,如果一个新方法被添加到接口中,那么该接口的所有实现类都必须覆盖该新方法,即使它们没有使用新功能。
在 Java 8 中,我们可以通过default在方法实现之前使用关键字来为新方法添加默认实现。
即使使用匿名类或函数式接口,如果我们看到某些代码是可重用的,并且我们不想在代码中的任何地方都定义相同的逻辑,我们可以编写这些代码的默认实现并重用它们。
例子
public interface YourInterface {
public void doSomeWork();
//A default method in the interface created using "default" keyword
default public void doSomeOtherWork(){
System.out.println("DoSomeOtherWork implementation in the interface");
}
}
class SimpleInterfaceImpl implements YourInterface{
/*
* Not required to override to provide an implementation
* for doSomeOtherWork.
*/
@Override
public void doSomeWork() {
System.out.println("Do Some Work implementation in the class");
}
/*
* Main method
*/
public static void main(String[] args) {
SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl();
simpObj.doSomeWork();
simpObj.doSomeOtherWork();
}
}
Run Code Online (Sandbox Code Playgroud)