[java] 인터페이스에 정의 된 메소드의 “기본”구현은 무엇입니까?

컬렉션 인터페이스에서 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이며 어떻게 작동합니까?



답변

에서 https://dzone.com/articles/interface-default-methods-java

Java 8에는 개발자가 이러한 인터페이스의 기존 구현을 중단하지 않고 인터페이스에 새 메서드를 추가 할 수있는 “기본 메서드”또는 (Defender 메서드) 새 기능이 도입되었습니다. 구체적인 클래스가 해당 메소드에 대한 구현을 제공하지 못하는 상황에서 기본값으로 사용할 인터페이스 정의 구현을 허용하는 유연성을 제공합니다.

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

public class ClassAB implements A {
}

사람들이 새로운 기능에 대해 처음 들었을 때 기본 방법에 대해 묻는 한 가지 일반적인 질문이 있습니다.

클래스가 두 개의 인터페이스를 구현하고 두 인터페이스가 동일한 서명으로 기본 메서드를 정의하면 어떻게됩니까?

이 상황을 설명하는 예 :

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();
    }
}


답변

이러한 메서드를 기본 메서드라고합니다. 기본 방법 또는 Defender 방법 은 Java 8에 새로 추가 된 기능 중 하나입니다 .

구체적인 클래스가 해당 메서드에 대한 구현을 제공하지 않는 경우 인터페이스 메서드가 기본값으로 사용되는 구현을 제공하도록 허용하는 데 사용됩니다.

따라서 인터페이스가있는 경우 기본 방법을 사용합니다.

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

유용한 링크:


답변

나는 약간의 조사를했고 다음을 발견했습니다. 도움이 되었기를 바랍니다.

기존 문제

일반 인터페이스 메서드는 추상으로 선언되며 인터페이스를 구현하는 클래스에서 정의되어야합니다. 이것은 선언 된 모든 메소드를 구현할 책임이있는 클래스 구현 자에게 ‘부담’합니다. 더 중요한 것은 ‘게시’후에는 인터페이스 확장이 불가능 함을 의미하기도합니다. 그렇지 않으면 모든 구현자가 구현을 조정하여 하위 소스 및 바이너리 호환성을 깨뜨려야합니다.

Java 8에 채택 된 솔루션

이러한 문제에 대처하기 위해 JDK 8의 새로운 기능 중 하나는 기본 메서드로 기존 인터페이스를 확장 할 수 있다는 것입니다. 기본 메소드는 선언 될뿐만 아니라 인터페이스에서도 정의됩니다.

주목해야 할 중요한 사항

  1. 구현자는 클래스를 구현할 때 기본 메서드를 구현하지 않도록 선택할 수 있습니다.
  2. 구현자는 일반 비 최종 클래스 메서드를 하위 클래스에서 재정의 할 수있는 것처럼 여전히 기본 메서드를 재정의 할 수 있습니다.
  3. 추상 클래스는 기본 메서드를 추상으로 (재) 선언하여 하위 클래스가 메서드를 다시 구현하도록 할 수도 있습니다 ( ‘재 추상화’라고도 함).


답변