# 아이템20 추상 클래스보다는 인터페이스를 우선하라

> Effective Java 3e 아이템 20를 요약한 내용 입니다.

자바가 제공하는 `다중 구현 메커니즘`은 `인터페이스`와 `추상 클래스`, 이렇게 두 가지다. 자바는 `단일 상속`만 지원하니, 추상 클래스 방식은 새로운 타입을 정의하는 데 커다란 제약을 안게 되는 셈이다. 반면 인터페이스가 선언한 메서드를 모두 정의하고 그 일반 규약을 잘 지킨 클래스라면 다른 어떤 클래스를 상속 했든 `같은 타입`으로 취급된다.

자바 플랫폼에서도 `Comparable`, `Iterable`, `AutoCloseable` 인터페이스가 새로 추가 됐을 때 표준 라이브러리의 수많은 기존 클래스가 이 인터페이스들을 구현한 채 릴리스됐다.

인터페이스는 `믹스인(mixin)` 정의에 안성맞춤이다. 믹스인이란 클래스가 구현할 수 있는 타입으로, 믹스인을 구현한 클래스에 원래의 '`주된 타입`'외에도 특정 선택적 행위를 제공한다고 선언하는 효과를 준다.

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

```
public interface Singer {
    AudioClip sing(Song s);
}
public interface SongWriter {
    Song compose(int chartPosition);
}

public interface SingerSongWriter extends Singer, Songwriter {
    AudioClip sing(Song s);
    Song compose(int chartPosition);
}
```

래퍼 클래스는 관용구와 함꼐 사용하면 인터페이스는 `기능을 향상`시키는 `안전`하고 강력한 수단이 된다.

인터페이스의 메서드 중 구현 방법이 명백한 것이 있다면, 그 구현을 `디폴트 메서드`로 제공해 프로그래머들의 일감을 덜어줄 수 있다. 디폴트 메서드를 제공할 때는 상속 하려는 사람을 위한 설명을 `@implSpec` 자바독 태그를 붙여 문서화해야 한다.

인터페이스는 `인스턴스 필드`를 가질 수 없고 public이 아닌 `정적 멤버`도 가질 수 없다. 마지막으로 여러분이 만들지 않은 인터페이스에는 `디폴트 메서드`를 추가할 수 없다.

인터페이스로는 타입을 정의하고, 필요하면 디폴트 메서드 몇 개도 함께 제공한다. 그리고 `골격 구현 클래스`는 나머지 메서드들 까지 구현한다. 이런 사용 사례가 `템플릿 메서드 패턴`이다.

구조상 골격 구현을 확장하지 못하는 처지라면 인터페이스를 직접 구현해야 한다. 이런 경우라도 인터페이스가 직접 제공하는 `디폴트 메서드`의 이점을 여전히 누릴 수 있다. 또한, 골격 구현 클래스를 우회적으로 이용할 수도 있다. 인터페이스를 구현한 클래스에서 해당 골격 구현을 확장한 `private 내부 클래스`를 정의하고, 각 메서드 호출을 내부 클래스의 인스턴스에 전달하는 것이다.

> 구체적인 사례가 필요하다

`단순 구현(simple implementation)`은 골격 구현의 작은 변종으로, `AbstractMap.SimpleEntry`가 좋은 예다. 단순 구현도 골격 구현과 같이 상속을 위해 인터페이스를 구현한 것이지만, 추상 클래스가 아니란 점이 다르다. 쉽게 말해 동작하는 가장 단순한 구현이다. 이러한 단순 구현은 그대로 써도 되고 필요에 맞게 확장해도 된다.

## 정리

일반적으로 `다중 구현`용 타입으로는 `인터페이스`가 가장 적합하다. 복잡한 인터페이스 라면 구현하는 수고를 덜어주는 골격 구현을 함께 제공하는 방법을 꼭 고려 해보자. 골격 구현은 '`가능한 한`' 인터페이스의 디폴트 메서드로 제공하여 그 인터페이스를 구현한 모든 곳에서 활용하도록 하는 것이 좋다. '`가능한 한`'이라고 한 이유는, 인터페이스에 걸려 있는 구현상의 제약 때문에 골격 구현을 `추상 클래스`로 제공하는 경우가 더 흔하기 때문이다.
