728x90
자바 8버전 이후부터 인터페이스에 기본 메소드(default 메서드)와 static 메서드를 사용할 수 있게 되었다.
왜 인터페이스는 default 메서드를 추가하였을까??
- 디폴트 메서드를 이용하면, 자바 API의 호환성을 유지하면서 라이브러리를 바꿀 수 있다.
- 디폴트 메서드는 다중 상속 동작이라는 유연성을 제공한다.
라이브러리 설계자 입장에서 인터페이스에 새로운 메서드를 추가하는 등 인터페이스를 바꾸고 싶을 때 문제가 발생한다.
왜냐하면, 인터페이스를 바꾸면 이전에 해당 인터페이스를 구현했던 모든 클래스의 구현도 고쳐야하기 때문이다.
이러한 문제를 해결하기 위해, 자바 8버전 이후부터는 인터페이스에 디폴트 메서드나 정적 메서드를 사용할 수 있게 되었다.
⇒ 인터페이스에 디폴트 메서드를 구현하면, 이 인터페이스를 상속 받은 클래스도 디폴트 메서드를 사용할 수 있다.
또한, 클래스는 여러 인터페이스를 상속 받을 수 있다.
그리고 인터페이스들이 각각 디폴트 메서드를 가지고 있다면 클래스는 여러개의 디폴트 메서드를 상속받아 사용할 수 있다.
다중 상속 동작 시 발생할 수 있는 충돌 문제가 있다.
자바에서는 아래 3가지 규칙을 지킴으로써 충돌 문제를 해결한다.
- 클래스가 항상 이긴다. 클래스나 슈퍼 클래스에서 정의한 메서드가 디폴트 메서드보다 우선권을 가진다.
- 1번 규칙 이외의 상황에서는 서브 인터페이스가 이긴다. 상속 관계를 갖는 인터페이스에서 같은 시그니처를 갖는 메서드를 정의할 때는 서브 인터페이스가 이긴다. 즉, B가 A를 상속받는다면 B가 A를 이긴다.
- 1번, 2번 규칙을 적용하고도 우선순위가 정해지지 않았다면, 인터페이스를 상속받는 클래스가 명시적으로 디폴트 메서드를 오버라이드하고 호출해야한다.
디폴트 메서드, 정적 메서드, 다중 동작 상속의 예 + 3번 규칙 예제
public interface A {
static void hi(){
System.out.println("hi from A");
}
default void hello(){
System.out.println("Hello from A");
}
default void A(){
System.out.println("A 디폴트 메서드");
}
}
public interface B {
default void hello(){
System.out.println("Hello from B");
}
default void B(){
System.out.println("B 디폴트 메서드");
}
}
public class C implements B,A{
@Override
public void hello() {
B.super.hello();
}
public static void main(String args[]){
A.hi(); // A의 static 메서드
C c = new C();
c.hello(); // hello 메스드 override!
c.A();
c.B();
}
}
728x90
'JAVA' 카테고리의 다른 글
final에 대하여 (4) | 2023.05.26 |
---|---|
정적 팩토리 메서드 (1) | 2023.05.23 |
enum 이 자식!! (2) | 2023.03.01 |
Date, Callender 클래스 LocalDateTime 클래스 + mysql과의 연결 (0) | 2022.09.26 |
람다식에 관하여 (0) | 2022.09.23 |