추상 클래스와 인터페이스의 공통점
- 자식클래스는 부모 클래스의 모든 것을 구현해주어야 한다. 하나라도 안된다면 자식 클래스(자식 인터페이스) 역시 추상클래스여야 한다.
- 그 자체만으로 인스턴스 생성은 불가능하다.
추상 클래스란?
: 클래스의 구현부 없는 미완성의 형태. 미완성 설계도. 메소드 몸통이 있을 수 있다.
- 추상클래스는 모든 메소드가 완성되지 않았다는 뜻이고 추상메소드는 구현부가 없다는 뜻이다. 몸통이 없는 추상 메소드라면 꼭 abstract를 명시하는 것이 좋다.
추상화: 여러 클래스들의 공통적인 부분을 뽑아서 공통의 부모인 추상클래스로 추상화 <-> 구체화
인터페이스란?
: 일종의 추상클래스이지만, 추상화의 정도가 높아서 static, default를 제외하고는 메소드 몸통이 없다. 따라서, 밑그림만 그려져있는 기본 설계도라고 볼 수 있다.
- 모든 멤버변수에는
public static final
가 생략되어있고, 모든 멤버함수에는public abstract
가 생략되어 있다. (JDK 1.8부터 static, 디폴트 메서드도 있긴하다.)- 모든 생략사항은 컴파일 시 컴파일러가 추가해준다.
- 디폴트 메소드: 추상 메소드의 기본적인 구현을 제공하는 메소드. 새로운 추상 메소드가 추가될 때, 모든 구현체에서 이걸 구현할 필요는 없다.
추상 클래스 vs 인터페이스
: 이펙티브 자바에서도 가능한 경우라면 인터페이스 사용을 권장하고 있고, java 창시자 제임스 고슬링은 다시 java를 설계한다면 추상 클래스를 없앨 것이라고 했다고 한다. 특별한 이유가 없다면 인터페이스를 사용하는 것이 좋을 것 같다.
다중상속 (extends)
: 일반적으로 자바에서는 다중 상속이 금지되어있다. 그러나 인터페이스의 경우는 다중 상속이 가능하다.
1
interface Fightable extends Movable, Attackable { }
인터페이스의 가장 큰 장점 두가지
- 관계 없는 클래스간 관계를 맺어줄 수 있다. 관계가 없으니 상속으로 묶기 애매한 경우,
~~~able
형태의 인터페이스를 구현하는 형태로 묶어준다면 관계가 형성된다. - DIP - 독립적인 프로그래밍: 선언과 구현을 분리시킨다. 인터페이스를 통해 클래스간 직접적인 관계를 간접적으로 만들면, 인터페이스에만 의존하기 때문에 계층간 의존이 줄어든다.
- 클래스를 사용하는 쪽과 클래스를 제공하는 쪽이 있다. 사용하는 쪽에서는 그냥 메소드의 선언부만 알고 사용하면 된다.
- A - B의 관계에서 A - I(interface) - B의 관계로 개선된다. e.g). JPA를 사용하다가 하이버네이트 구현체를 딴거로 갈아끼워도 Service 코드에는 영향이 미치지 않도록 구현 가능하다.
개념적 차이
- 일반적으로 인터페이스에서는 어떠한 기능 또는 행위를 하는데 필요한 메서드를 제공한다는 의미를 강조하기 위해 ~able 형태의 네이밍이 많다.
- 추상클래스에서는 is-a의 상속 개념이 어울리는 클래스에서 사용하는게 적절해보인다.
Reference)
자바의 정석 3판