简体   繁体   English

接口中定义的方法的“默认”实现是什么?

[英]What is the “default” implementation of method defined in an Interface?

In the Collection Interface I found a method named removeIf() that contains its implementation. 在Collection Interface中,我找到了一个名为removeIf()的方法,其中包含了它的实现。

default boolean removeIf(Predicate<? super E> filter) {
    Objects.requireNonNull(filter);  
    boolean removed = false;  
    final Iterator<E> each = iterator();   
    while (each.hasNext()) {  
        if (filter.test(each.next())) {  
            each.remove();  
            removed = true;  
        }  
    }  
    return removed;  
}  

I want to know if there is any way to define method body in an interface? 我想知道是否有任何方法可以在接口中定义方法体?
What is the default keyword and how does it work? 什么是default关键字,它是如何工作的?

From https://dzone.com/articles/interface-default-methods-java 来自https://dzone.com/articles/interface-default-methods-java

Java 8 introduces “Default Method” or (Defender methods) new feature, which allows developer to add new methods to the interfaces without breaking the existing implementation of these interface. Java 8引入了“默认方法”或(Defender方法)新功能,它允许开发人员在不破坏这些接口的现有实现的情况下向接口添加新方法。 It provides flexibility to allow interface define implementation which will use as default in the situation where a concrete class fails to provide an implementation for that method. 它提供了允许接口定义实现的灵活性,在具体类无法为该方法提供实现的情况下,该实现将默认使用。

public interface A {
    default void foo(){
       System.out.println("Calling A.foo()");
    }
}

public class ClassAB implements A {
}

There is one common question that people ask about default methods when they hear about the new feature for the first time: 当人们第一次听到新功能时,有一个常见问题是人们会询问默认方法:

What if the class implements two interfaces and both those interfaces define a default method with the same signature? 如果该类实现了两个接口并且这两个接口都定义了具有相同签名的默认方法,该怎么办?

Example to illustrate this situation: 举例来说明这种情况:

public interface A {  
    default void foo(){  
        System.out.println("Calling A.foo()");  
    }  
}

public interface B {
    default void foo(){
        System.out.println("Calling B.foo()");
    }
}


public class ClassAB implements A, B {

}  

This code fails to compile with the following result: 此代码无法使用以下结果进行编译:

java: class Clazz inherits unrelated defaults for foo() from types A and B

To fix that, in Clazz, we have to resolve it manually by overriding the conflicting method: 要解决这个问题,在Clazz中,我们必须通过覆盖冲突的方法来手动解决它:

public class Clazz implements A, B {
    public void foo(){}
}

But what if we would like to call the default implementation of method foo() from interface A instead of implementing our own. 但是如果我们想从接口A调用方法foo()的默认实现而不是实现我们自己的方法呢。

It is possible to refer to A#foo() as follows: 可以如下引用A#foo():

public class Clazz implements A, B {
    public void foo(){
       A.super.foo();
    }
}

Those methods are called default methods. 这些方法称为默认方法。 Default method or Defender method is one of the newly added features in Java 8. 默认方法Defender方法是Java 8中新增的功能之一。

They will be used to allow an interface method to provide an implementation used as default in the event that a concrete class doesn't provide an implementation for that method. 它们将用于允许接口方法在具体类不提供该方法的实现的情况下提供用作缺省的实现。

So, if you have an interface, with a default method: 所以,如果你有一个接口,使用默认方法:

public interface Hello {
    default void sayHello() {
        System.out.println("Hello");
    }
}

The following class is perfectly valid: 以下类完全有效:

public class HelloImpl implements Hello {

}

If you create an instance of HelloImpl : 如果您创建HelloImpl的实例:

Hello hello = new HelloImpl();
hello.sayHello();  // This will invoke the default method in interface

Useful Links: 有用的链接:

I did a bit of research and i found the following. 我做了一些研究,我发现了以下内容。 Hope this helps. 希望这可以帮助。

Existing problem 存在问题

Normal interface methods are declared as abstract and must be defined in the class that implements the interface. 普通接口方法声明为抽象,必须在实现接口的类中定义。 This 'burdens' the class implementer with the responsibility to implement every declared method. 这会给班级实施者带来“负担”,他们有责任实施所有宣称的方法。 More importantly, this also means that extending an interface is not possible after 'publication'. 更重要的是,这也意味着在“发布”之后无法扩展接口。 Otherwise, all implementers would have to adapt their implementation, breaking backwards source and binary compatibility. 否则,所有实施者都必须调整其实现,打破后向源和二进制兼容性。

Solution adopted in Java 8 Java 8中采用的解决方案

To cope with these problems, one of the new features of JDK 8 is the possibility to extend existing interfaces with default methods. 为了解决这些问题,JDK 8的一个新功能是可以使用默认方法扩展现有接口。 Default methods are not only declared, but also defined in the interface. 默认方法不仅被声明,而且还在接口中定义。

Important points to note 重点要注意

  1. Implementers can choose not to implement default methods in implementing class. 实现者可以选择不在实现类中实现默认方法。
  2. Implementers can still override default methods, like regular non-final class methods can be overridden in subclasses. 实现者仍然可以覆盖默认方法,例如可以在子类中重写常规非final类方法。
  3. Abstract classes can even (re)declare default methods as abstract, forcing subclasses to reimplement the method (sometimes called 're-abstraction'). 抽象类甚至可以(重新)将默认方法声明为抽象,从而强制子类重新实现该方法(有时称为“重新抽象”)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM