본문 바로가기

Dev.BackEnd/JAVA

[Java8] 2. Default Method(디폴트 메서드)

2. 디폴트 메서드

Java 8에서는 디폴트 메서드라는 것을 사용하여 메서드 구현을 포함하는 인터페이스를 정의할 수 있다. 인터페이스에서 이미 구현을 했으니 해당 인터페이스를 구현하는 클래스에서는 추가된 메서드의 구현을 추가적으로 할 필요가 없다. 결과적으로 기존 인터페이스를 구현하는 클래스는 자동으로 인터페이스에 추가된 새로운 메서드의 디폴트 메서드를 상속받게 된다.

디폴트 메서드를 활용하면 자바 API의 호환성을 유지하면서 라이브러리를 변경할 수 있다.
기존에는 이미 공개된 라이브러리를 수정할 때 인터페이스에 메서드를 추가하게 되면 해당 인터페이스를 구현하고 있는 클래스에 모두 메서드를 구현해줘야 했지만 디폴트 메서드를 통해 구현하면 그렇게 하지 않아도 된다. 훨씬 더 유연해진 것이다.

이와 같은 방식으로 추가된 두 가지 메서드에는 List 인터페이스의 sort 메서드와 Collection 인터페이스의 stream 메서드이다.
default void sort(Comparator<? super E> c) {
Collections.sort(this, c);
}
반환 형식인 void 앞에 default라는 keyword가 추가되었다.

그러면 Java8의 인터페이스와 추상클래스의 차이점이 무엇인가?
같은 점이 정말 많아졌지만 여전히 차이점은 존재한다. 추상 클래스는 인스턴스 변수(필드)로 공통 상태를 가질 수 있지만 인터페이스는 변수(필드)를 가질 수 없다. 그리고 당연한 얘기겠지만 추상 클래스는 하나만 상속받을 수 있고 인터페이스는 여러 개를 구현할 수 있다. 디폴트 메서드를 포함하는 인터페이스를 여러 개 구현할 수 있다는 것은 자바에서도 다중 상속을 지원하게 되었다는 뜻이다.

선택형 메서드
인터페이스를 구현할 때 필요없는 추상 메서드에 대해서도 반드시 구현을 해줬어야 하므로 빈 구현을 했다면, 디폴트 메서드를 통해 인터페이스에서부터 구현을 해주면 클래스에서는 쓸데없는 빈 구현 코드가 사라지게 되는 것이다.

동작 다중 상속
중복 되지 않는 최소한의 인터페이스를 유지한다면 코드에서 동작을 쉽게 재사용하고 조합할 수 있다.


Q1. 디폴트 메서드를 해당 인터페이스를 구현하는 클래스에서 오버라이딩 할 수 있는가?
물론이다. 할 수 있다.

Q2. 동일한 시그니처를 갖는 디폴트 메서드를 상속받는 상황에서는 어떻게 동작하는가?
다른 클래스나 인터페이스로부터 같은 시그니처를 갖는 메서드를 상속받을 때는 다음 세 가지 규칙을 따라야 한다.
첫째, 클래스나 슈퍼 클래스에서 정의한 메서드가 디폴트 메서드보다 우선권을 갖는다.
둘째, 클래스나 슈퍼 클래스에 메서드 정의가 없을 때는 디폴트 메서드를 정의하는 서브 인터페이스가 선택된다.
마지막으로 인터페이스 간의 우선순위가 없을 때 즉, 위 두 규칙으로 우선권이 확립되지 않았다면 해당 시그니처의 메서드를 오버라이딩해야 한다.

2. end