반응형

1. 서론

이번 포스팅에서는 Chapter13의 디폴트 메서드에 대해 진행하도록 하겠습니다.

 

2. 변화하는 API

인터페이스에 새로운 메서드를 추가하는 등 인터페이스를 바꾸고 싶을때는 문제가 발생합니다. 

 

변경 인터페이스를 상속하고 있는 클래스들에 모두 영향이 가기 때문이죠.

 

이러한 문제점을 java에서는 디폴트 메서드라는 개념을 도입하여  해결하였습니다.

 

디폴트 메서드가 왜 필요한지 예제를 통해 알아보겠습니다.

 

처음 아래처럼 Resizable 인터페이스를 만들어 제공하였습니다.

 

public interface Resizable {
    int getWidth();
    int getHeight();
    void setWidth();
    void setHeight();
    void setAbsoluteSize(int width, int height);
}

public class Ellipse implements Resizable {
	...
}

 

시간이 지나 요구사항을 처리하다보니 Resizable에 setRelativeSize(int wFactor, int hFactor) 가 필요함을 깨달았습니다.

 

이때 바로 문제가 생깁니다.

 

Resizable를 구현한 클래스들은 모두 setRelativeSize 메서드를 구현해야 하기 때문입니다.

 

3. 디폴트 메서드란 무엇인가?

디폴트 메서드는 인터페이스에 구현 메서드를 놓을 수 있는 새로운 시그니쳐입니다.

 

이를 통해, 위와같은 문제점을 해결할 수 있습니다.

 

사용법으로는 default 라는 키워드로 메서드를 정의하면 됩니다.

 

아래는 디폴트 메서드를 사용한 예제입니다.

 

public interface Sized {
    int size();
    default boolean isEmpty() {
        return size() == 0;
    }
}

 

 

 

 

 

 

 

반응형

 

 

 

 

 

 

 

4. 디폴트 메서드 활용 패턴

디폴트 메서드를 활용하는 방식으로는 두가지가 있습니다.

 

  • 선택형 메서드
  • 동작 다중 상속

 

1) 선택형 메서드

 

인터페이스에는 간혹 구현 클래스에서 크게 중요하지 않은 메서드를 정의할때가 있습니다.

 

그로인해, 구현 클래스들은 메서드 오버라이드만 할 뿐 실제 바디에는 내용이 없게 하는 코드들이 생기게 됩니다.

 

하지만 디폴트 메서드를 사용하면 기본 메서드 구현을 인터페이스에 상주할 수 있어 이러한 문제를 해결하게 됩니다.

 

2) 동작 다중 상속

 

디폴트 메서드를 통해 여러 인터페이스를 상속하고 있는 클래스들은 사용할 수 있는 동작이 풍부해집니다.

 

아래는 코드로 해당 이점을 보여주는 예제입니다.

 

public interface Rotatable {
    void setRotationAngle(int angleInDegrees);
    int getRotationAngle();
    default void rotateBy(int angleInDegrees) {
        setRotationAngle(getRotationAngle() + angleInDegrees);
    }
}

public interface Resizable {
    int getWidth();
    int getHeight();
    void setWidth();
    void setHeight();
    void setAbsoluteSize(int width, int height);
    default void setRelativeSize(int wFactor, int hFactor) {
        setAbsoluteSize(getWidth() / wFactor, getHeight() / hFactor);
    }
}

public interface Moveable {
    int getX();
    int getY();
    void setX(int x);
    void setY(int y);
    default void moveHorizontally(int distance) {
        setX(getX() + distance);
    }

    default void moveVertically(int distance) {
        setY(getY() + distance);
    }
}

public class Moster implements Rotatable, Moveable, Resizable {

}

 

5. 해석 규칙

디폴트 메서드로 인해 개발자에게 장점만 제공된것은 아닙니다.

 

단점으로는 같은 시그니처를 갖는 디폴트 메서드를 상속 받는 상황이 생길 수 있다는 것입니다.

 

자바에서는 이러한 경우를 대비해 아래와 같은 3가지 규칙을 세워 메서드의 상속 우선순위를 가지도록 했습니다.

 

  1. 클래스가 항상 이긴다. 클래스나 슈퍼클래스에서 정의한 메서드가 디폴트 메서드보다 우선권을 갖습니다.
  2. 1번 다음으로는 서브 인터페이스가 이깁니다.
  3. 1번과 2번과 같은 상황이 없고, 디폴트 메서드에 대해 순위가 정해지지 않은 경우에는 상속 클래스에서 명시적으로 디폴트 메서드를 오버라이드하여 호출해야 합니다.

 

6. 마무리

이번 포스팅에서는 Chapter13 디폴트 메서드 대해 진행하였습니다.

다음에는 Chapter14 자바 모듈 시스템에 대해 포스팅하겠습니다.

반응형

+ Recent posts