Search

Item 20. 추상 클래스보다 인터페이스를 우선하라

생성일
2023/07/25 05:50
챕터
4장 - 클래스와 인터페이스

인터페이스를 쉽게 구현해 넣을 수 있다.

자바 8부터 인터페이스도 디폴트 메서드(defalut method)를 제공할 수 있기에, 기존 클래스도 implements를 넣어 손쉽게 새로운 인터페이스를 구현해 넣을 수 있다.
반면 추상 클래스는 기존 클래스에 끼워넣기 쉽지 않고, 두 클래스가 같은 추상 클래스를 확장하길 원한다면 추상 클래스가 계층 구조상 두 클래스의 공통 조상이어야 가능하다. 이 방식은 추상 클래스의 모든 자손이 해당 클래스를 상속받아야 하는데, 클래스 계층구조에 혼란을 일으켜 좋지 않다.

인터페이스는 믹스인(mixin)을 정의하는데 사용될 수 있다.

믹스인이란 객체지향 언어에서 다른 클래스에서 사용되기 위해 만들어진 클래스나 인터페이스를 의미하고, 주된 기능에 선택적 기능을 혼합(mixed in)한다는 의미로 클래스에 원래의 주된 기능(타입) 외에 특정 선택적 행위를 제공한다는 선언이다.
대표적 예시로 Comparable은 해당 인터페이스를 구현한 클래스들의 인스턴스들끼리 순서를 정할 수 있다고 선언하는 믹스인 인터페이스이다.
하지만 추상 클래스는 기존 클래스에 덧씌울 수 없고, 다중 상속이 불가능하기 때문에 상속 클래스 계층구조에는 믹스인을 삽입하기 어렵다.

인터페이스로는 계층구조가 없는 타입 프레임워크를 만들 수 있다.

public interface Singer { AudioClip sing(Song s); } public interface SongWriter { Song compose(int chartPosition); }
Java
복사
이런 인터페이스들을 정의하면 아래와 같이 Singer와 Songwriter를 모두 구현해도 문제가 되지 않는다.
public interface SingSongwriter extends Singer, Songwriter { AudioClip strum(); void actSensitive(); }
Java
복사
이와 같은 구조를 클래스로 만드려면 가능한 조합 전부를 각각의 클래스로 정의하여 비대한 계층구조를 가진 클래스가 된다.

래퍼 클래스와 인터페이스를 함께 사용하여 기능 향상을 노리자

추상 클래스로 타입을 정의해두면 해당 타입에 기능을 추가하는 방법은 상속 밖에 없고, 상속해서 만든 클래스는 래퍼 클래스보다 활용도가 떨어지고 깨지기 쉽다.
인터페이스와 추상 골격 구현(skeletal implementation) 클래스를 함께 제공하여 인터페이스로는 타입을 정의하거나 디폴트 메서드를 제공하고 골격 구현 클래스로 나머지 메서드들을 구현하여 인터페이스와 추상 클래스의 장점을 모두 챙길 수 있다. 이러한 방법을 템플릿 메서드 패턴이라 부른다.