TIL

인터페이스 (Interface)

승무_ 2023. 8. 25. 18:48

Java 8 이후의 Interface의 특징

1. 인스턴스를 생성할 수 없고 상수만 가질 수 있다.

2. 메서드 body가 없는 추상 메서드를 가진다.

3. default 메서드, static 메서드를 가질 수 있다.

default 메서드가 추가된 이유

이미 작성된 인터페이스에서 기능을 추가하려고 할 때, 디폴트 메서드가 없다면 구현체 클래스들이 전부 새로운 메서드를 override해야하지만, 디폴트 메서드가 있으면 추가 작업없이 하위호환 가능

 

 

Interface를 써야 하는 이유

public interface Singer {
    void sing();
}

public interface SongWriter {
    void compose();
}

public class SingerSongWriter implements Singer, SongWriter {
    public void sing(){
        System.out.println("노래 부르기!");
    }
    
    public void compose(){
        System.out.println("작곡하기");
    }
}

위 예시 처럼 다중상속이 가능하기 때문이다.

 

Q. 다음과 같은 계층 구조이면 다중 상속 없이 SingerSongWriter를 표현할 수 있지 않나요?

가능은 하나, SongWriter 생성 시 SongWriter에게 불필요한 Singer의 메서드나 필드가 상속되어 독자적인 SongWriter를 만들 수 없다.

 

Interface 사용시 주의점

Q. 디폴트 메서드가 포함된 인터페이스를 다중 상속시 다이아몬드 문제가 발생 안하나요?

다이아몬드 문제 : 다중 상속 시, 부모 클래스에 같은 이름의 메서드가 있을 때, 어떤 메서드를 상속 받아야 하는지 판별할 수 없는 문제


문제가 발생하나, 컴파일러 내부 우선순위 규칙으로 이를 해결

우선순위 1. 구현하는 클래스 

public interface A{
    default void someMethod(){
        System.out.println("Default A");
    }
}

public class C implements A {
    // C에서 someMethod 호출하면 "Default C" 출력
    @Override
    public void someMethod(){
        System.out.println("Default C");
    }
}

우선순위 1. 부모클래스

public interface A{
    default void someMethod(){
        System.out.println("Default A");
    }
}

public interface B{
    default void someMethod(){
        System.out.println("Default B");
    }
}

public class C implements A {
    @Override
    public void someMethod(){
        System.out.println("Default C");
    }
}

public class D extends C implements B {
    // D에서 someMethod 호출하면 부모클래스 "Default C" 출력
}

우선순위 2. 상속받는 인터페이스

public interface B{
    default void someMethod(){
        System.out.println("Default B");
    }
}

public class C implements B {
    // C에서 someMethod 호출하면 부모클래스 "Default B" 출력
}

우선순위 3. 사용할 인터페이스 직접 명시

public interface A{
    default void someMethod(){
        System.out.println("Default A");
    }
}

public interface B{
    default void someMethod(){
        System.out.println("Default B");
    }
}

public class C implements A, B {
    @Override
    public void someMethod(){
        A.super().someMethod();
    }
}

'TIL' 카테고리의 다른 글

OAuth 2.0  (0) 2023.08.14
[JAVA] GC  (0) 2023.08.04
Servlet & Spring Web MVC  (0) 2023.07.20
MySQL 아키텍처  (0) 2023.07.19
Hash table & BST  (0) 2023.06.28