이번 글을 읽기 위해서는 추상클래스와 인터페이스의 차이점을 알아야한다.
자바8 버전이전에 가장 큰 차이점은 추상 클래스는 구현부가 있는 메소드를 가질 수 있지만 인터페이스는 가질 수 없다는점이 제일 컸다.
자바8 버전에서 디폴트 메소드가 추가되면서 인터페이스도 구현부를 가질 수 있게 되었다.
그렇다면 우리는 여기서 세가지 의문을 가질 수 있다.
- 인터페이스와 추상클래스는 똑같지 않나요?
- 인터페이스와 추상클래스 어떤것이 더 좋은건가요?
- 인터페이스와 추상클래스 어떻게 사용하나요?
인터페이스와 추상클래스는 똑같지 않나요?
여전히 다릅니다.
자바는 다중상속이 안되기에 추상클래스를 사용하면 다른 상속을 받지 못합니다.
인터페이스를 사용한다면 여러개를 구현할 수 있습니다.
인터페이스는 변수는 public static final, 메소드는 public 인 반면 추상클래스는 static, final 이 아닌 변수선언도 가능하며 메소드의 접근범위를 제어할 수 있습니다.
인터페이스와 추상클래스 어떤것이 더 좋은건가요 ?
결론부터 말씀드리면 상황에 따라 다르지만 일반적으로 인터페이스를 사용하는것이 좋습니다.
한가지 예제로 상황마다 장단점을 알아보겠습니다.
시나리오는 아래와 같습니다.
학생 점수는 매기는 기능을 가지는 클래스가 있다.
이 클래스에 정렬, 출력, 삭제 기능을 추가 한다.
상황1. print()와 sort()는 연관이 없다.
이럴때 인터페이스를 사용한다면 아래와 같은 인터페이스를 만들어서 구현만 하면됩니다.
public interface addFunction {
void print();
void sort();
void delete();
}
하지만 상속을 사용한다면 이것이 is-a의 관계인가, 상속을 받음으로써 오류가 날 확률이 없는가? 등 여러가지 고민을 해봐야합니다.
(상속을 받으면 상위클래스 구현부에 따라 동작이 바뀔 수 있습니다. 간단한 예제는 여기에서 확인하실 수 있습니다.)
이렇게 중간에 기능을 추가할때 일반적으로 인터페이스가 유리합니다.
상황2. print()는 sort()를 실행한후에 출력해야하며 sort는 외부에 공개되면 안되며 delete는 사용자에게 작성토록한다.
이러한 상황에서는 인터페이스로 해결을 하기는 조금 까다롭습니다.
인터페이스의 접근제어자는 public이라 sort가 공개될 수 밖에 없으며 사용될때 exception 처리를 해주어야합니다.
그렇게 된다면 사용자에게 예상치못한 오류와 혼란을 안겨줄 수 있습니다.
이럴때 추상 클래스를 사용한다면 아래와 같이 구현할 수 있습니다.
public abstract class AbstractClass {
public void print(){
sort();
}
private void sort(){
// 구현
}
abstract public void delete();
}
인터페이스와 추상클래스 어떻게 사용하나요?
다중구현 상황에서는 '최대한' 인터페이스를 사용합니다.
인터페이스는 추가, 제거가 간편하기 때문입니다.
하지만 인터페이스의 제약으로 인하여 인터페이스를 사용하지 못할때는 추상클래스를 사용합니다.
참고 : effective java 3/E, Item 20
'개발 > JAVA' 카테고리의 다른 글
[enum] enum의 활용방법 (0) | 2020.07.11 |
---|---|
[effective java 3/E] 제네릭 <로 타입은 사용하지 말라> (0) | 2020.07.11 |
[effective java 3/E] 상속보다는 컴포지션을 사용하라 (0) | 2020.07.05 |
[effective java 3/E] equals는 일반 규약을 지켜 재정의하라. (0) | 2020.07.05 |
[effective java 3/E] 자원을 직접 명시하지말고 의존 객체 주입을 사용하라 (2) | 2020.06.28 |
댓글