2월 15, 2024

[JAVA] 추상클래스 (abstract class)와 인터페이스(Interface)의 차이점

JAVA에서 추상클래스 (abstract class)와 인터페이스 (Interface)는 비슷한 기능을 제공한다. 그렇기에 이 둘 사이의 차이는 무엇이고 인터페이스의 존재 이유에 대한 질문이 자주 등장한다.

 

추상클래스와 인터페이스의 공통점과 차이점부터 살펴본 뒤, 각각을 더 자세히 살펴보겠다.


추상클래스와 인터페이스의 공통점

  • 추상 메서드 구현 강제:

    추상클래스와 인터페이스 둘 다 존재하는 추상 메서드의 구현을 강제한다는 공통점이 있다. 즉, 추상클래스를 상속받거나 인터페이스를 구현할 때 반드시 존재하는 추상 메서드를 구현해야 하며, 이를 구현하지 않는다면 에러가 발생한다. 
  • 인스턴스화 불가능:

    인스턴스화, 즉 객체를 만드는 것이 불가능하다. Java에서 class를 가지고 주로 자유롭게 객체를 만들곤 했찌만, 추상클래스와 인터페이스는 일종의 틀이기 때문에 인스턴스화가 불가능하다는 공통점을 가지고 있다. 

    객체를 생성하기 위해서 추상클래스는 상속을 받아야 하고 인터페이스는 구현을 해야 한다. 즉 이렇게 상속을 하거나 구현을 한 하위의 클래스는 객체 생성이 가능하나, 그 자체로는 객체 생성이 불가능하다는 것이 공통점이다.

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

  • 가장 중요한 차이점인 사용 목적의 차이:

    추상클래스와 인터페이스에는 여러 차이점이 존재하지만 그 중 가장 중요한 차이점은 사용 목적에서 찾을 수 있다고 생각한다. 추상클래스의 경우 상속을 받아서 자식 클래스에서 부모 클래스의 기능을 확장시키는 용도라면, 인터페이스는 큰 틀을 잡아놓고 구현한 하위 클래스들이 같은 기능을 구현하도록 강제한 느낌이라고 생각하면 된다. 

  • 다중상속의 여부:

    두 번째로 큰 차이점은 다중상속의 여부이다. 추상클래스의 경우 다중상속이 불가능하나, 인터페이스의 경우 다중상속이 가능하다. JAVA에서 '다중상속은 불가능하다'라고 주로 알려져있는데 이를 인터페이스까지 확장하면 다중상속이 가능하다. 즉, 추상클래스는 extends를 사용하여 하나의 class만 상속받을 수 있다면, 인터페이스의 경우 implements 키워드를 사용하여 여러 인터페이스를 구현할 수 있다.

  • 접근자의 차이:

    인터페이스의 메소드를 작성할때 앞의 접근자를 적지 않아도 public abstract로 간주된다. 또한 모든 변수는 public static final의 접근자를 가진다. 물론 abstract method가 아니더라도 Java 8부터는 default method를 통해 일반 메소드의 구현도 가능해졌지만 인터페이스의 대부분 메소드는 abstract method라고 생각할 수 있다. 

    반면, 추상클래스의 경우 모든 변수가 static final은 아니기 때문에 인터페이스보다는 접근자가 자유롭다고 표현할 수 있다.

추상클래스와 인터페이스의 대략적인 공통점과 차이점을 살펴보았다. 이제 추상클래스와 인터페이스를 하나씩 살펴보면서 언제 사용하면 좋은지에 대해 이야기해보도록 하겠다.

 

 1. 추상클래스 ( abstract class ) 

추상클래스는 class 내부에 추상 메서드가 하나 이상 포함되는 경우 혹은 abstract의 선언이 붙은 경우를 의미한다. 이러한 추상클래스를 상속하여 일반 자식 클래스에서는 구현한 추상 메서드를 반드시 구현해주어야 한다. 단일 상속만이 허용되며, 이 말은 여러 추상클래스를 동시에 상속할 수 없다는 말과 같다. 

 

추상클래스는 상속을 받아서 기능을 확장하기 때문에 주로 클래스 간의 관련성이 높은 경우 abstract class를 상속받아 추상메서드를 구현한다. 또한 위의 차이점에서 언급되었듯이, interface는 반드시 변수가 static과 final의 접근자를 가지기 때문에 이와 같은 제약을 받을 필요가 없는 경우 (변수가 static과 final이 아니어야 하는 경우) 에 사용할 수 있다. 

 

 2. 인터페이스 ( Interface ) 

대표적인 인터페이스 중 Comparable Interface를 모두 들어보았을 것이다. 이러한 Comparable Interface를 구현하는 class들은 모두 다 제각각이다. compareTo라는 메서드를 구현하면서 객체 간의 순서를 정해주는 역할을 할 뿐, Comparable Interface를 구현하는 class 간의 공통점은 찾아볼 수 없다. 즉 추상클래스의 경우 이를 상속하면서 자식 class에서 기능을 확장하는 역할이 더 크기 때문에 주로 관련성이 높은 class들에서 상속을 받아 사용하지만 Interface는 그렇지 않은 것을 알 수 있다. 

 

또한 협업프로젝트의 경우에 모두가 동일한 기능을 구현하여 프로젝트를 해야 한다라고 했을 때 인터페이스 skeleton code를 만들어 놓고 이를 구현하여 코드를 작성할 수도 있다. 인터페이스는 이와 같이 '반드시 이 메서드를 구현해라'의 느낌이 강하다. 

 

또한 인터페이스의 특징 중 다중상속이 가능하다는 특징을 활용해 여러 인터페이스의 기능이 필요할 경우 다중상속을 하여 사용할 수도 있다.


이처럼 인터페이스와 추상클래스는 비슷한 것처럼 보이지만 사용목적이나 세부적인 특징에 있어서 차이점을 보인다. 상황에 알맞은 것을 사용해보자.