[Java] 추상클래스와 인터페이스: 무엇을 선택할까?

Woomin Wang ·2025년 4월 29일

[Java]

목록 보기
7/10
post-thumbnail

추상 클래스인터페이스의 개념은 학습했지만, 실제 개발에서 언제 어떻게 적절히 활용해야 할지에 대한 감을 잡기 어렵다. 이에 따라 상황에 맞는 사용 목적과 활용 방식을 정리하여, 객체 지향 설계에 대한 이해를 더욱 깊이 다지고자 한다.


추상 클래스(Abstract Class)

  • 공통적인 속성(변수)과 동작(메서드)을 가진 미완성 클래스다.
  • 일부 메서드는 직접 구현하고, 일부 메서드는 자식 클래스가 반드시 구현하도록 강제할 수 있다.
  • 인스턴스를 직접 생성할 수 없고, 반드시 상속받아서 사용해야 한다.
  • extends 키워드로 상속하며, 단일 상속만 가능하다.

인터페이스(Interface)

  • 클래스가 반드시 구현해야 하는 동작 목록만 정의하는 일종의 "규약"이다.
  • 모든 메서드는 기본적으로 구현 없이 선언만 한다. (단, Java8부터 defaulut, static 메서드 정의 가능)
  • 필드는 무조건 public static final 상수만 허용된다.
  • implements 키워드로 구현하며, 여러 개의 인터페이스를 동시에 구현할 수 있다.

Java8 이후, 인터페이스도 "기본 제공 기능"을 가질 수 있다?

기존에는 인터페이스가 메서드 시그니처만 선언하고, 구현은 자식 클래스가 직접 해야 했다. 하지만, Java 8부터는 인터페이스 안에서도 default 메서드를 통해 인터페이스도 기본 구현을 가질 수 있게 되었다.

✔️ default 메서드 예시 코드

interface Animal {
    void sound();

    default void sleep() {
        System.out.println("잠을 잡니다.");
    }
}

class Dog implements Animal {
    @Override
    public void sound() {
        System.out.println("멍멍!");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.sound();  // 멍멍!
        dog.sleep();  // 잠을 잡니다.
    }
}

추상 클래스 vs 인터페이스: 언제 사용할까?

추상 클래스 사용이 적합한 경우

  • 상속 관계가 명확한 경우: 부모 클래스에서 기본 동작을 정의하고, 자식 클래스에서 이를 확장하거나 변경할 때 사용

  • 상태 공유가 필요한 경우: 자식 클래스들이 공통된 상태를 관리하거나 공유해야 할 때 유용

  • 공통 기능이 많을 때: 여러 클래스가 공통적으로 가지는 기능을 한 곳에 정의하고 이를 재사용할 때 사용

인터페이스 사용이 적합한 경우

  • 서로 관련 없는 클래스들이 같은 동작을 해야 할 때: 여러 클래스들이 공통된 기능을 구현해야 하며, 서로 다른 상속 계층을 가질 때 유용

  • 다중 상속이 필요한 경우: 자바는 다중 상속을 지원하지 않지만, 인터페이스는 여러 개를 동시에 구현할 수 있기 때문에 다양한 기능을 한 클래스에서 구현

  • 동작의 일관성을 보장하고 싶을 때: 다양한 클래스에서 동일한 동작을 강제하고 싶을 때 인터페이스를 사용

추상 클래스: "is-a" 관계를 표현한다. → 객체의 본질적 속성을 설계할 때 사용.
(ex. "Dog는 Animal이다.")

인터페이스: "can-do" 능력을 표현한다. → 객체의 부가적 기능을 설계할 때 사용.
(ex. "Dog는 Bark할 수 있다.")


추상 클래스와 인터페이스의 적절한 사용 예시

1. Creature 클래스 (추상 클래스)

  • Creature는 모든 생물이 가져야 할 공통 속성과 동작을 정의한다.
  • "Animal은 Creature이다", "Plant는 Creature이다"처럼, "is-a" 관계를 표현한다.

2. Animal, Plant 클래스 (상속)

  • AnimalPlantCreature를 상속받고, 각각의 고유한 동작을 구현한다.
  • 상속을 통해 본질적 속성을 설계한다.

3. Barkable 인터페이스

  • DogCatAnimal을 상속받고, 추가로 Barkable 인터페이스를 구현한다.
  • "Dog는 Bark할 수 있다", "Cat은 Bark할 수 있다"처럼, "can-do" 능력을 표현한다.
  • Plant는 짖을 수 없기 때문에 Barkable을 구현하지 않는다.

4. Eatable 인터페이스

  • 먹을 수 있는 생물들만 Eatable 인터페이스를 구현하여 eat() 기능을 가진다.
  • 예를 들어, Dog는 먹을 수 있으므로 eat()을 구현하지만, Rose는 먹을 수 없기 때문에 Eatable을 구현하지 않습니다.
  • "Dog는 먹을 수 있다"처럼, "can-do" 능력을 표현한다.

참고 자료 - 추상 클래스와-인터페이스의 차이

profile
Backend Developer

0개의 댓글