인터페이스 default 메서드와 static 메서드

2023. 4. 27. 22:29JAVA

728x90

자바 8버전 이후부터 인터페이스에 기본 메소드(default 메서드)와 static 메서드를 사용할 수 있게 되었다.

 

왜 인터페이스는 default 메서드를 추가하였을까??

 

  1. 디폴트 메서드를 이용하면, 자바 API의 호환성을 유지하면서 라이브러리를 바꿀 수 있다.
  2. 디폴트 메서드는 다중 상속 동작이라는 유연성을 제공한다.

라이브러리 설계자 입장에서 인터페이스에 새로운 메서드를 추가하는 등 인터페이스를 바꾸고 싶을 때 문제가 발생한다.

왜냐하면, 인터페이스를 바꾸면 이전에 해당 인터페이스를 구현했던 모든 클래스의 구현도 고쳐야하기 때문이다.

 

이러한 문제를 해결하기 위해, 자바 8버전 이후부터는 인터페이스에 디폴트 메서드나 정적 메서드를 사용할 수 있게 되었다.

 

⇒ 인터페이스에 디폴트 메서드를 구현하면, 이 인터페이스를 상속 받은 클래스도 디폴트 메서드를 사용할 수 있다.

 

또한, 클래스는 여러 인터페이스를 상속 받을 수 있다.

그리고 인터페이스들이 각각 디폴트 메서드를 가지고 있다면 클래스는 여러개의 디폴트 메서드를 상속받아 사용할 수 있다.

 

다중 상속 동작 시 발생할 수 있는 충돌 문제가 있다.

 

자바에서는 아래 3가지 규칙을 지킴으로써 충돌 문제를 해결한다.

  1. 클래스가 항상 이긴다. 클래스나 슈퍼 클래스에서 정의한 메서드가 디폴트 메서드보다 우선권을 가진다.
  2. 1번 규칙 이외의 상황에서는 서브 인터페이스가 이긴다. 상속 관계를 갖는 인터페이스에서 같은 시그니처를 갖는 메서드를 정의할 때는 서브 인터페이스가 이긴다. 즉, B가 A를 상속받는다면 B가 A를 이긴다.
  3. 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