상속을 공부할 때, 클래스 간의 다중 상속은 지원하지 않는다고 배웠다. (extends a, b 불가능)
근데 인터페이스는 다중 상속이 가능하다. (implements a, b 가능)
왜 인터페이스는 가능한지 의문이 들어서 내용을 정리해보려고 한다.
우선 클래스 간의 다중 상속은 왜 안될까?
자식 클래스가 2개의 부모 클래스를 상속 받는다고 가정하자.
부모 A, B 클래스에 각각 show() 라는 메서드가 정의되어 있다. 그러면 자식 클래스는 show()메서드를 A, B 중 어느 것을 상속받아야 할까?
자식 클래스에서는 알 수 없기 때문에 이미 구현된 동일한 메서드를 상속받는 것은 불가능하다.
인터페이스는 왜 다중 상속이 가능할까?
인터페이스는 메서드가 정의되어 있지 않다. 이 뜻은 인터페이스를 상속받으면 무조건 해당 클래스에서 메서드를 정의해야 한다는 뜻이다.
A, B 인터페이스에 동일한 show() 라는 추상 메서드가 있으면 A,B 를 implements 한 클래스 C에서 구현을 하기 때문에 문제가 되지 않는다.
예시를 들어보자, 아래와 같이 Sleepable, Flyable 인터페이스에 동일한 sleep() 추상 메서드가 있다.
public interface Sleepable {
void sleep();
default void wakeUp() {
System.out.println("wake Up");
}
}
public interface Flyable {
void sleep();
default void fly() {
System.out.println("fly");
}
}
그리고 위의 두 개의 인터페이스를 상속받는 Bird 클래스를 작성하면 결국 아래와 같이 sleep() 추상 메서드를 재정의하기 때문에 문제가 되지 않는 것을 알 수 있다.
public class Bird implements Flyable, Sleepable{
@Override
public void sleep() {
System.out.println("sleep");
}
}
추상 메서드는 결국 재정의를 하기 때문에 다중 상속이 가능하다는 것을 이해했는데, 자바 8 이후부터 인터페이스 안에 default 메서드라고 해서 메서드를 구현해놓을 수 있다. 여기서 한가지 의문이 들었는데..
그럼 A, B 인터페이스 안에 동일한 default 메서드를 구현해놓으면 다중 상속이 안될까?
위에서 설명했듯이, 클래스 간의 다중 상속은 어떤 부모 클래스의 메서드를 상속받아야 할지 알 수 없기 때문에 불가능하다. 그럼 각 인터페이스에 default 메서드를 구현해놓으면 똑같이 구현되어 있는 메서드이기 때문에 안되야 하는거 아닌가 라는 의문이 들었다.
결론은 가능하다..
public interface Poet {
default void write() {
System.out.println("Poet's default method");
}
}
public interface Writer {
default void write() {
System.out.println("Wirter's default method");
}
}
위와 같이 Poet, Writer 인터페이스에 동일한 write() 라는 default 메서드를 작성했다.
그 다음, 두 개의 인터페이스를 implements 하면 아래의 사진과 같이 오류가 발생할 것 이다.
아래와 같이 Override를 해주면 된다. 결국 default 메서드도 상속받은 클래스에서 재정의를 하면 문제가 없다.
public class MultiTalent implements Poet, Writer{
@Override
public void write() {
Poet.super.write();
Writer.super.write();
}
}
개인적인 의견으로는 클래스 간의 다중 상속은 허용하지 않던 상태에서 이 문제를 해결하고자, 인터페이스에 default 메서드라는 기능이 추가된게 아닐까싶다.. (정확한 자료는 아직 찾지 못함)
결론
- 클래스 간의 다중상속은 불가능하다.
- 인터페이스는 다중상속이 가능하다.
- 여러 인터페이스에 동일한 default 메서드가 있어도 클래스에서 재정의하여 사용가능하다.
'☕️ Java' 카테고리의 다른 글
[Java] List 인터페이스 - ArrayList 클래스 (1) | 2023.05.30 |
---|---|
[Java] Collection Framework (2) | 2023.05.18 |
[Java] String, StringBuilder, StringBuffer의 차이 (0) | 2023.04.26 |
[Java] Comparable과 Comparator (0) | 2023.04.25 |
[Java] toString()을 Override 하는 이유 (0) | 2023.04.07 |