Java 什么是「;“违约”;接口中定义的方法的实现?

Java 什么是「;“违约”;接口中定义的方法的实现?,java,interface,java-8,Java,Interface,Java 8,在集合接口中,我找到了一个名为removeIf()的方法,该方法包含它的实现 default boolean removeIf(Predicate<? super E> filter) { Objects.requireNonNull(filter); boolean removed = false; final Iterator<E> each = iterator(); while (each.hasNext()) {

在集合接口中,我找到了一个名为
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;  
}  

default boolean removeIf(Predicate这些方法称为default方法。default方法或Defender方法是Java8中最常用的方法之一

它们将用于允许接口方法提供一个在具体类没有为该方法提供实现时用作默认值的实现

因此,如果您有一个带有默认方法的接口:

public interface Hello {
    default void sayHello() {
        System.out.println("Hello");
    }
}
以下类别完全有效:

public class HelloImpl implements Hello {

}
如果创建
HelloImpl
的实例:

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

有用的链接:


我做了一些研究,发现了以下几点。希望这能有所帮助

存在的问题

普通接口方法被声明为抽象的,必须在实现接口的类中定义。这“加重”了类实现者实现每个声明方法的责任。更重要的是,这也意味着在“发布”后不可能扩展接口。否则,所有实现者都将我们必须调整它们的实现,打破向后的源代码和二进制兼容性

java8中采用的解决方案

为了解决这些问题,JDK 8的一个新特性是可以使用默认方法扩展现有接口。默认方法不仅在接口中声明,而且在接口中定义。

需要注意的要点

  • 实现者可以选择不在中实现默认方法 实现类
  • 实现者仍然可以覆盖默认值 方法,就像常规的非final类方法一样,可以在中重写 子类
  • 抽象类甚至可以(重新)声明默认方法 作为抽象,强制子类重新实现方法(有时 称为“我们抽象”)
  • Java8引入了“默认方法”或(Defender方法)新特性,允许开发人员在不破坏这些接口的现有实现的情况下向接口添加新方法。它提供了允许接口定义实现的灵活性,在具体类无法为该方法提供实现的情况下,该实现将作为默认值使用

    当人们第一次听说新功能时,会问一个关于默认方法的常见问题:

    如果类实现了两个接口,并且这两个接口都定义了具有相同签名的默认方法,该怎么办

    举例说明这种情况:

    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 {
    
    }  
    
    此代码无法编译,结果如下:

    java: class Clazz inherits unrelated defaults for foo() from types A and B
    
    为了解决这个问题,在Clazz中,我们必须通过覆盖冲突的方法手动解决它:

    public class Clazz implements A, B {
        public void foo(){}
    }
    
    但是,如果我们想从接口A调用方法foo()的默认实现,而不是实现我们自己的方法,该怎么办呢

    可以将A#foo()引用如下:

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

    请参阅这篇关于默认相关文章的文章,这样,如果一个类实现了一个接口而没有实现它的方法就可以了吗?就我使用的Java7而言,这是不允许的。@Anikethakur。这在Java 8之前是不允许的。此功能仅在Java 8中添加。您可以避免在imple中给出默认方法的实现menting类。@PawanMishra。请参阅我前面的评论。不,您不需要在实现类中提供默认接口方法的实现。@PawanMishra,您可以重写它。没有任何限制,例如您只需要使用默认实现。这是一个向前的步骤,最终将避免被多重继承所困扰!谢谢,非常好的解释。在我有机会提问之前,你已经回答了我所有的问题。为什么不使用抽象呢?@AstolfoHoscher你只能扩展一个类,但可以实现多个接口。
    public class Clazz implements A, B {
        public void foo(){
           A.super.foo();
        }
    }