다음 인터페이스를 살펴보자.
interface Person {
long getId();
default String getName() { return "John Q. Public"; }
}
이 인터페이스는 추상 메서드 getId와 디폴트 메서드 getName을 포함하고 있다. 당연히 Person 인터페이스를 구현하는 구체 클래스concrete class는 getId의 구현을 제공해야 하지만, getName의 구현은 그대로 두거나 오버라이드하는 방법 중 선택할 수 있다.
디폴트 메서드는 인터페이스와 해당 인터페이스의 대부분 혹은 모든 메서드를 구현한 추상 클래스를 제공하는 고전적인 패턴(예를 들면, Collection/AbstractCollection 또는 WindowListener/WindowAdapter)의 종말을 선고했다. 이제는 인터페이스에서 바로 메서드를 구현할 수 있다.
만일 똑같은 메서드가 한 인터페이스의 디폴트 메서드로 정의되어 있고, 슈퍼클래스나 다른 인터페이스의 메서드로도 정의되어 있으면 무슨 일이 일어날까? 스칼라나 C++ 같은 언어는 이와 같은 모호함을 해결하는 복잡한 규칙을 갖추고 있다. 다행히도 자바에서는 이 규칙이 훨씬 단순하다. 자바의 규칙은 다음과 같다.
1. 슈퍼클래스가 우선한다. 슈퍼클래스에서 구체적인 메서드를 제공하는 경우, 이와 이름 및 파라미터 타입이 같은 디폴트 메서드는 단순히 무시된다.
2. 인터페이스들이 충돌한다. 어떤 슈퍼인터페이스에서 디폴트 메서드를 제공하고, 또 다른 인터페이스에서 (디폴트 메서드든 아니든) 이름 및 파라미터 타입이 같은 메서드를 제공하는 경우에는 해당 메서드를 오버라이드해서 충돌을 해결해야 한다.