S E P H ' S

[Java] 인터페이스 vs 추상클래스 본문

Programing & Coding/JAVA

[Java] 인터페이스 vs 추상클래스

yoseph0310 2024. 1. 15. 16:22

인터페이스(Interface)와 추상클래스(Abstract Class)의 차이점

추상 클래스는 클래스 내에 하나 이상의 추상 메소드를 포함하거나 abstract로 정의된 클래스를 말하고 인터페이스는 모든 메소드가 추상 메소드인 경우이다. (Java 8에서는 default 키워드를 사용해 일반 메소드의 구현도 가능함)

 

두 개념의 차이는 명확하다. 생김새도 다르고 사용방법도 다르다. 그러나 역할이 비슷하여 혼동이 많이 오기도 한다. 추상클래스와 인터페이스 모두 상속받는 클래스 혹은 구현하는 구현체가 추상 메소드를 구현하도록 강제한다. 이렇게 보면 추상 클래스에 추상 메소드를 여러개 두거나 전부 추상 메소드만 두면 될 것 같은데 인터페이스가 존재하는 이유는 무엇일까?

 

비슷해보이지만 두 개념의 목적을 자세히 짚어보자. 추상클래스의 목적은 추상클래스를 상속받아 기능을 사용하고 확장시키는데 있고 인터페이스는 함수의 껍데기만 존재하고 구현체들에게 함수의 구현을 강제한다. 구현을 강제함으로써 구현체의 같은 동작을 보장할 수 있다. 애매하지만 명확히 다른 목적이다.

 

다시 본론으로 돌아가자면 인터페이스가 존재하는 이유는 자바가 다중 상속을 지원하지 않기 때문이다. 다중 상속은 아래와 같이 상위클래스를 두는 것을 말한다.

 

class MyCar extends Car, Truck {
    @Override
    public void drive() {
        // 코드
    }
}

 

위 코드에서 MyCar 클래스는 Car, Truck 클래스를 상속받고 있다. MyCar가 움직이기 위해서 drive() 메소드를 실행한다. 만약 여기서 Car, Truck 클래스가 모두 drive라는 메소드를 갖고 있다면 어떤 메소드가 실행되는 것인지 모호해진다. 이러한 점 때문에 자바는 다중 상속을 지원하지 않는다. (사실 예제에서처럼 Car, Truck 과 같은 개념을 클래스로 만드는 것보다는 Car, Truck의 공통된 특징을 담은 하나의 클래스 혹은 인터페이스를 만들어 사용하는 것이 바람직하다.)

 

class MyPhone implements Phone, Message {
    @Override
    public void call() {
        // 코드
    }
    
    @Override
    public void sendMessage() {
        // 코드
    }
}

 

MyPhone 클래스는 Phone 인터페이스와 Message 인터페이스를 구현한 구현체이고 Phone과 Message 인터페이스는 각각 전화를 거는 기능과 메시지를 보내는 기능을 갖고 있다. Phone, Message 인터페이스를 구현함으로써 MyPhone은 전화를 걸거나 메시지를 보내는 기능을 두 인터페이스로부터 구현하여 사용하게된다. 이는 다중 상속이 아니라 Phone, Message를 구현하는 구현체들이 모두 동일한 동작을 보장하도록 하기 위함이다.

 

정리하자면, 추상 클래스는 해당 추상 클래스의 기능을 이용하거나 확장하고자 함이고 다중 상속의 모호함 때문에 하나만 상속받을 수 있다. 인터페이스는 해당 인터페이스를 구현한 구현체들에 대해 동일한 동작을 보장하도록 하기 위함이다. 물론 이러한 것들이 의미가 있도록 하려면 각각 다른 인터페이스들이 서로 같은 동작을 하는 일이 없도록 하는 좋은 설계가 필요할 것이다.