JAVA/Effective Java

클래스와 인터페이스 - 규칙 18 추상 클래스 대신 인터페이스를 사용하라.

반응형

자바는 다중 상속이 되지 않기 때문에, 추상 클래스 보다 인터페이스를 사용하는 것이 좋다.

믹스인
인터페이스는 믹스인을 정의하는 데 이상적이다.
=> 믹스인은 클래스가 주 자료형 이외에 추가로 구현할 수 있는 자료형으로 어떤 선택적 기능을 제공한다는 사실을 선언하기 위해 쓰인다.
=> 예를 들면, Comparable은 어떤 클래스가 자기 객체를 다른 객체와의 비교 결과에 따른 순서를 갖는다고 선언할 때 쓰는 인터페이스이다.

이런 믹스인 기능을 추상클래스에 할 수 없다. 
=> 클래스가 가질 수 있는 상위 클래스는 하나 이기 때문에 좋은 방법이 아니다.

인터페이스는 여러 속성을 합쳐서 새로운 속성을 만들 수 있다.
=> singer와 SongWriter 속성을 합쳐서 새로운 인터페이스를 만들 수 있다.



1
2
3
4
5
6
7
8
9
10
public interface singer {
}
 
public interface SongWriter {
 
}
 
public interface SingerSongWriter extends Singer, SongWriter {
 
}
cs




하지만 이런 조합을 인터페이스가 아닌 클래스를 이용한다면 별도의 클래스를

계속 만들어 주어야 한다.

필요한 속성이 n개가 있을 때 조합의 가짓수는 2의 n승으로 이것을 조합 폭증이라고 한다.

추상 골격 구현 (Abstract skeletal implemetation)
해당 추상 골격 구현 클래스를 중요 인터페이스마다 두면, 인터페이스의 장점과 추상 클래스의 장점을 결합 할 수 있다.

방법
=> 인터페이스로는 자료형을 정의하고, 구현하는 일은 골격 구현 클래스에 맡기면 된다.

Ex) List



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 골격 구현 위에서 만들어진 완전한 List 구현
static List<Integer> intArrayAsList(final int[] a) {
  if (a == null
     throw new NullPointerExeception();
 
  return new AbstractList<Integer>() {
     public Integer get(int i) {
        return null;
     }
 
     @Oveerride
     public Integer set(int i, Integer val) {
         int oldVal = a[i];
         a[i] = val;
         return oldVal;
      }
 
      public int size() {
         return a.length;
      }
  };
}
cs



인터페이스 보다 추상 클래스가 좋은 경우는
새로운 기능이 추가되었을 때, 인터페이스는 새로운 메서드를 추가하더라도 새로 모두 구현해 주어야 하지만 추상클래스의 경우에는 그대로 하위클래스에서 사용할 수 있다는 것이다.
=> 하지만 Java 8에서 default 메소드를 통해 이 단점 또한 해결이 되었다.

또한 
public 인터페이스의 경우 공개되고 난 다음에는, 인터페이스 수정이 거의 불가능 하다. 그러므로 처음 설계부터 잘 구현해야 한다는 단점이 있다.

출처 : 조슈아 블로크, 『 Effective Java 2/E』, 이병준 옮김, 인사이트(2014.9.1), 규칙18 인용.



반응형