Language/Java

추상 클래스와 인터페이스 비교하기

olsohee 2024. 1. 14. 15:38

추상 클래스

  • 추상 클래스는 하나 이상의 추상 메소드를 갖는 클래스를 말하며, 추상 메소드를 갖는다는 점을 제외하면 일반 클래스와 동일하다. 따라서 추상 클래스는 멤버 변수와 일반 메소드를 가질 수 있다. 
  • 추상 클래스는 미완성이므로 그 자체로 객체를 생성(인스턴스화)할 수 없다. 
  • 추상 클래스를 상속받는 자식 클래스는 추상 메소드를 반드시 오버라이딩해야 한다. 
  • 다중 상속이 불가능하다. 
  • 참고로, 추상 메소드를 사용하면 좋은 점은 다음과 같다.
    • 부모 클래스의 메소드를 추상 메소드가 아닌 일반 메소드로 정의할 수 있다. 그리고 상속받는 자식 클래스가 해당 메소드를 재정의하면 된다. 그런데 실수로 자식 클래스에서 메소드 오버라이딩을 하지 않은 경우 오류가 발생하지 않는다. 따라서 의도치 않은 결과가 나올 수 있다. 반면, 자식 클래스가 반드시 재정의해야 하는 메소드를 부모 클래스에서 추상 메소드로 정의하면, 부모 클래스를 상속받는 자식 메소드가 해당 메소드를 오버라이딩하지 않으면 컴파일 단계에서 오류가 발생한다. 따라서 의도치 않은 실수를 방지할 수 있다.

인터페이스

  • 인터페이스도 추상 클래스와 마찬가지로 추상 메소드를 갖는다. 하지만 추상 클래스와 달리 일반 메소드 또는 멤버 변수를 가질 수 없다. 오직 추상 메소드와 default 메소드, static 메소드, 상수(static final)만 가질 수 있다.
  • 따라서 인터페이스의 모든 멤버 변수는 public static final이어야 하며, 이를 생략할 수 있다.
  • 그리고 인터페이스의 모든 메소드는 public abstract이어야 하며, 이를 생략할 수 있다. (Java 8부터는 static, default 메소드도 가질 수 있다.)
  • default 메소드
    • default 메소드는 반드시 구현할 필요가 없는 메소드이다. 따라서 인터페이스에 새로운 메소드를 추가했을 때, 이를 default 메소드로 선언하면, 인터페이스를 구현한 모든 클래스가 해당 메소드를 추가로 구현하지 않아도 된다. 재정의가 필요한 자식 클래스만 default 메소드를 오버라이딩하면 된다. 
    • default 메소드는 추상 메소드와 달리 몸통{...}이 있어야 한다. 그리고 디폴트 메소드 역시 접근 제어자가 public이어야 하며, 생략 가능하다.
  • 다중 상속이 가능하다.

추상 클래스와 인터페이스의 차이

추상 클래스와 인터페이스는 상속받는 클래스가 추상 메소드를 구현하도록 강제한다는 점에서 하는 일이 비슷하다. 그러나 둘의 목적이 다르다. 

 

추상 클래스는 상속받아서 기능을 확장시키는 데 있다.  즉, extends 키워드 그대로 부모 클래스의 기능들을 하위로 확장시키는 것으로 볼 수 있다. 반면, 인터페이스는 구현 객체들의 "동일한 실행 기능을 보장"하기 위해 사용된다. 즉, implements 키워드처럼 인터페이스에 정의된 메소드를 각 클래스의 목적에 맞게 동일한 기능을 갖도록 구현하는 것으로 볼 수 있다. 

 

그리고 추상 클래스는 상속받을 각 객체들의 공통점을 모아 추상화시켜 놓은 것이다. 따라서 상속 관계를 타고 올라갔을 때, 같은 부모 클래스를 상속하며, 부모 클래스의 기능을 구현해야 하는 경우에 사용한다. 반면, 인터페이스는 상속 관계를 타고 올라갔을 때, 다른 부모 클래스를 상속받더라도 같은 기능이 필요할 때 사용한다.


Reference