본문 바로가기
book/modern java in action

Chapter 13 디폴트 메서드

by eunoia_DB 2023. 2. 11.

인터페이스와 구현 클래스가 존재할 때 인터페이스에 새로운 메서드를 추가한다면 구현 클래스에도 새로운

메서드의 구현을 해야 할 것이다. 하지만 메서드를 추가할 때 클래스를 관리할 수 있는 상황이라면 상관이

없겠지만 관리할 수 없는 상황이라면 문제가 발생할 것이다.

 

위와 같은 상활을 예로 들어, 어떤 한 설계자가 미리 설계한 API가 있고 이를 배포까지 한 상태이다.

배포 후 API를 사용하다 추가해야 할 기능이 생겼고 이를 위해 설계자는 인터페이스에 새로운 메서드를 추가했다.

 

그런데 만약 메서드 추가 이전에 기존 API를 구현하여 사용하고 있는 사용자의 구현 클래스는 어떻게 될까?

아마 사용자가 직접 구현한 메서드는 동작하지 않을 것이다. 물론 인터페이스에 새로운 메서드를 추가했지만 이를

구현하지 않고 사용한다면 동작은 될 것이다. 하지만 누군가는 새로 추가된 메서드를 구현해서 사용할 수 있기

때문에 미리 에러 발생에 대한 예방을 해야 한다. 이런 문제점을 해결할 수 있는 방법에는 무엇이 있을까?

 

바로 디폴트 메서드를 활용하면 위와 같은 문제점을 해결할 수 있다.

디폴트 메서드란 말 그대로 default 키워드로 시작되는 메서드로 이를 사용하면 인터페이스 내부에서

메서드 구현이 가능해지며 이를 상속받은 구현 클래스는 메서드를 별도로 구현하지 않아도

디폴트 메서드를 사용할 수 있다.

 

이런 디폴트 메서드를 위와 같은 상황에 접목시키면 문제를 쉽게 예방할 수 있다.

디폴트 메서드가 정의된 인터페이스를 구현 클래가 상속받으면 인터페이스의 기본 구현을 그대로

상속하므로 인터페이스에 종속되지 않고 자유롭게 새로운 메서드를 추가할 수 있다. 또한 디폴트 메서드는

다중 상속 동작이 가능하기 때문에 유연성을 제공하면서 프로그램 구성에 도움을 준다

 

 

디폴트 메서드가 낯설게 느껴질 수 있지만 우리가 자주 사용하는 인터페이스에도

이러한 디폴트 메서드가 많이 사용되고 있다. 그 예로는 List 인터페이스의 sort 메서드가 있다.

 

 

- List 인터페이스 내 sort default 메서드

 

- sort 메서드가 기본적으로 제공하는 기능에 대한 설명

 

 

 

 

디폴트 메서드 활용 패턴

디폴트 메서드를 이용하는 방식에는 두가지가 있다

 

1. 선택형 메서드

인터페이스를 구현하는 클래스에서 메서드 내용이 비어있는 경우가 있는데 이러한 예로 Iterator 인터페이스의

remove 메서드가 있다. remove 메서드는 Iterator의 메서드 중 자주 사용되지 않기 때문에 따로 메서드를 구현

하지 않고 디폴트 메서드로 기본 구현 제공하는 형태이다. 이러한 방법을 통해 불필요한 코드 제거가 가능하다.

 

2. 동작 다중 상속

추상 클래스와 다르게 인터페이스는 여러개 상속받아 구현할 수 있다.

예로 ArrayList 클래스는 한개의 추상 클래스와 네 개의 인터페이스를 상속받고 있는데 여러 인터페이스를

상속받을 수 있으므로 여러 인터페이스 내에 구현된 디폴트 메서드 또한 자동으로 사용할 수 있게 된다.

 

ArrayList가 상속 받는 추상 클래스 및 인터페이스

 

 

그런데 만약 두 개 이상의 인터페이스에서 같은 디폴트 메서드를 구현하고 있다면 

메서드 실행의 우선순위는 어떻게 될까? 이는 자바가 컴파일을 할 때 규칙을 가진다.

 

해석 규칙

1) 구현 클래스 내에서 정의한 메서드가 디폴트 메서드보다 우선권을 가진다.

2) 1번 이외에 상황에서는 서브 인터페이스가 우선순위를 가진다. 즉 B 인터페이스가 A 인터페이스를 상속받는다면

    B가 서브 인터페이스가 되고 B의 디폴트 메서드가 우선권이 된다.

3) 만약 1, 2 번 과정을 거쳤는데도 우선순위가 정해지지 않았다면 인터페이스들을 상속받는

    구현 클래스가 명시적으로 디폴트 메서드를 오버라이드하고 호출해야 한다.

 

이 3가지 외에 여러 예외 상황이 있는데 (2번에서 서브 인터페이스가 없고 동등한 상태의 인터페이스일 때)

이러한 경우 자바 컴파일러가 에러를 발생시킨다.

 

이러한 에러는 자바 8에서 지원하는 super를 사용하여 해결할 수 있는데 super를 통해

사용할 인터페이스와 디폴트 메서드를 지정하는 것이 가능하다. 

방법: (인터페이스 명).super.(디폴트 메서드 명) 

 

 

 

 

 

 

 

 


Reference

 

참고 도서명: 모던 자바 인 액션

 

댓글