인터페이스에 정의 된 메소드의 "기본"구현은 무엇입니까?


91

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



답변:


162

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

18
감사합니다, 정말 좋은 박람회입니다. 내가 질문 할 기회를 갖기 전에 당신은 내 모든 질문에 대답했습니다.
Jeff Hutchins

대신 추상을 사용하지 않는 이유는 무엇입니까?
Astolfo Hoscher

1
@AstolfoHoscher 하나의 클래스 만 확장 할 수 있지만 여러 인터페이스를 구현할 수 있습니다.
Charles Wood

49

이러한 메서드를 기본 메서드라고합니다. 기본 방법 또는 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

유용한 링크:


클래스가 인터페이스를 구현하고 메서드를 구현하지 않아도 괜찮습니까? Java7에 관한 한 내가 사용하는 것은 허용되지 않습니다.
아니 켓 딴

2
트윗 담아 가기 이것은 Java 8 이전에는 허용되지 않습니다.이 기능은 Java 8에서만 추가됩니다. 구현 클래스에서 기본 메소드 구현을 제공하지 않아도 됩니다.
Rohit Jain

1
@PawanMishra. 내 이전 댓글을 참조하십시오. 클래스를 구현할 때 기본 인터페이스 메서드를 구현할 필요가 없습니다.
Rohit Jain

1
@PawanMishra 당신은 그것을 무시할 수 있습니다. 기본 구현 만 사용해야한다는 제한은 없습니다.
아니 켓 딴

4
다중 상속으로 인해 당혹스러워하지 않는 전진 단계!
Xtreme Biker

17

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

기존 문제

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

Java 8에 채택 된 솔루션

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

주목해야 할 중요한 사항

  1. 구현자는 클래스를 구현할 때 기본 메서드를 구현하지 않도록 선택할 수 있습니다.
  2. 구현자는 일반 비 최종 클래스 메서드를 하위 클래스에서 재정의 할 수있는 것처럼 여전히 기본 메서드를 재정의 할 수 있습니다.
  3. 추상 클래스는 기본 메서드를 추상으로 (재) 선언하여 하위 클래스가 메서드를 다시 구현하도록 할 수도 있습니다 ( '재 추상화'라고도 함).
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.