java

인터페이스 VS 추상 클래스

curiousKidd 2024. 12. 18. 18:39
반응형

개발자라면 한 번쯤은 ‘인터페이스’와 ‘추상 클래스’에 대해 헷갈렸던 경험이 있을 것입니다. 둘 다 ‘추상화’라는 공통된 목표를 가지지만, 실제 사용 방식과 설계 철학에서는 큰 차이를 보입니다. 이번 글에서는 인터페이스와 추상 클래스의 차이점을 이해하기 쉽게 설명하고, 언제 어떤 것을 사용해야 할지에 대해 알아보겠습니다.

추상 클래스란?

추상 클래스는 ‘미완성 클래스’라고 할 수 있습니다. 이는 하나 이상의 추상 메서드(구현되지 않은 메서드)를 포함하며, 해당 클래스를 상속받는 하위 클래스에서 이 메서드를 반드시 구현해야 합니다. 하지만 단순히 추상 메서드만 포함할 수 있는 것이 아니라, 일반 메서드(구현된 메서드)와 상태(멤버 변수)도 가질 수 있다는 점에서 강력한 유연성을 제공합니다.

특징

  • 하위 클래스와의 강한 연관성: 추상 클래스는 상속 관계를 통해 하위 클래스들에게 공통된 로직과 구조를 제공합니다.
  • 상태 유지 가능: 멤버 변수를 가질 수 있어 상태를 관리할 수 있습니다.
  • 일반 메서드 포함 가능: 구현된 메서드를 포함하여 기본 동작을 정의할 수 있습니다.
  • 단일 상속만 가능: 한 클래스는 하나의 추상 클래스만 상속받을 수 있습니다.

예제 코드

abstract class Animal {
    String name;

    abstract void makeSound(); // 추상 메서드

    void eat() { // 일반 메서드
        System.out.println(name + " is eating.");
    }
}

class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("Woof!");
    }
}

인터페이스란?

인터페이스는 ‘추상화의 극단적인 형태’라고 할 수 있습니다. 인터페이스에 선언된 메서드는 기본적으로 구현을 가질 수 없으며, 인터페이스를 구현하는 클래스는 이 메서드를 반드시 정의해야 합니다. 그러나 Java 8 이후로는 디폴트 메서드와 정적 메서드를 통해 일부 구현을 제공할 수 있는 유연성이 추가되었습니다.

특징

  • 구현 강제: 인터페이스를 구현한 클래스는 인터페이스의 모든 메서드를 반드시 구현해야 합니다.
  • 다중 구현 가능: 클래스는 여러 개의 인터페이스를 구현할 수 있습니다.
  • 상태를 가질 수 없음: 멤버 변수를 가질 수 없습니다.
  • 디폴트 메서드 및 정적 메서드: Java 8부터 디폴트 메서드(기본 구현 제공)와 정적 메서드를 사용할 수 있습니다.

예제 코드

interface Flyable {
    void fly(); // 추상 메서드
}

interface Swimmable {
    void swim();
}

class Duck implements Flyable, Swimmable {
    @Override
    public void fly() {
        System.out.println("Duck is flying.");
    }

    @Override
    public void swim() {
        System.out.println("Duck is swimming.");
    }
}

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

특징 추상 클래스 인터페이스
목적 상속 관계에서 공통 로직 제공 다양한 클래스에 공통 기능 제공
메서드 구현 추상 메서드와 일반 메서드 모두 포함 가능 기본적으로 추상 메서드만 포함
상태 유지 멤버 변수 가질 수 있음 멤버 변수 가질 수 없음
상속/구현 제한 단일 상속만 가능 다중 구현 가능
유연성 구현된 메서드로 기본 동작 제공 가능 디폴트 메서드로 일부 구현 가능 (Java 8 이상)

언제 사용해야 할까?

  1. 공통 로직과 상태를 공유하고 싶다면? 추상 클래스를 사용하세요. 예를 들어 동물 클래스처럼 공통 속성(name)과 동작(eat)을 공유해야 한다면 적합합니다.
  2. 다양한 클래스에 동일한 기능을 강제하고 싶다면? 인터페이스를 사용하세요. 예를 들어 날거나(Flyable), 헤엄치는(Swimmable) 동작은 여러 클래스에서 구현될 수 있습니다.
반응형