default 메소드의 등장
- 인터페이스는 기능에 대한 선언만 가능, 실제 구현 로직은 포함될 수 없다.
- 자바 8부터 등장한
default 메소드
는 인터페이스 내부에서도 로직이 포함된 메소드를 선언할 수 있게 한다.
interface MyInterface {
default void printHello() {
System.out.println("Hello World");
}
}
- 이를 구현하는 클래스는
@Override
가능하다.
default 메소드 등장 이유
- 자바 기본서 ‘자바의 신’에서는
default 메소드
에 대한 존재 이유를 아래와 같이 설명한다.
💡 ...(중략) ... 바로 "하위 호환성"때문이다. 예를 들어 설명하자면, 여러분들이 만약 오픈 소스코드를 만들었다고 가정하자. 그 오픈소스가 엄청 유명해져서 전 세계 사람들이 다 사용하고 있는데, 인터페이스에 새로운 메소드를 만들어야 하는 상황이 발생했다. 자칫 잘못하면 내가 만든 오픈소스를 사용한 사람들은 전부 오류가 발생하고 수정을 해야 하는 일이 발생할 수도 있다. 이럴 때 사용하는 것이 바로 default 메소드다. (자바의 신 2권)
- 인터페이스의 기본 구현을 그대로 상속하므로 인터페이스에 자유롭게 새로운 메소드를 추가할 수 있게 된다.
- 호환성을 유지하면서 API를 바꿀 수 있다.
- 바이너리 호환성 : 변경 이후에도 에러 없이 기존 바이너리가 실행될 수 있는 상황
- 소스 호환성 : 코드를 고쳐도 기존 프로그램을 성공적으로 재컴파일할 수 있는 상황
- 동작 호환성 : 코드를 바꾼 다음에도 같은 입력값이 주어지면 같은 동작을 하는 상황
default 메소드의 규칙
- 클래스가 항상 이긴다. 클래스나 슈퍼클래스에서 정의한 메소드가 디폴트 메소드보다 우선권을 갖는다.
- 1번 규칙 이외의 상황에서는 서브 인터페이스가 항상 이긴다. 즉, B가 A를 상속받는 다면 B가 A를 이긴다.
- 여전히 디폴트 메소드의 우선순위가 결정되지 않았다면 여러 인터페이스를 상속받은 클래스가 명시적으로 디폴트 메소드를 오버라이드 하고 호출해야한다.
public interface A {
default void hello() {
System.out.println("Hello from A");
}
}
public interface B extends A{
default void hello() {
System.out.println("Hello from B");
}
}
public class C implements B, A {
public static void main(String args[]) {
new C().hello();
}
}
default 메소드의 활용
- 선택형 메소드
- 동작 다중 상속