인터페이스와 추상 클래스의 차이에 대해 설명해 주세요.

인터페이스는 "무엇을 할 수 있는가(능력)" 를 정의하고, 추상 클래스는 "무엇인가(본질)" 를 정의합니다.

핵심 비교

항목인터페이스추상 클래스
목적기능/능력 명세공통 기반 정의
다중 구현O 여러 개 가능X 단일 상속만
필드상수만 가능일반 필드 가능
생성자XO
메서드추상 메서드 (default 가능)추상 + 일반 메서드
접근제어자public만제한 없음
키워드implementsextends

인터페이스

// "날 수 있다", "수영할 수 있다" → 능력 정의
interface Flyable {
    void fly();  // 구현 강제
}

interface Swimmable {
    void swim();
}

// 다중 구현 가능
class Duck implements Flyable, Swimmable {
    @Override
    public void fly()  { System.out.println("날다"); }
    @Override
    public void swim() { System.out.println("수영하다"); }
}

class Airplane implements Flyable {
    @Override
    public void fly() { System.out.println("비행하다"); }
}

추상 클래스

// "동물이다" → 본질/공통 기반 정의
abstract class Animal {
    private String name;  // 공통 필드

    public Animal(String name) {  // 생성자 가능
        this.name = name;
    }

    // 공통 동작 → 일반 메서드로 구현
    public String getName() { return name; }

    // 동물마다 다름 → 추상 메서드로 강제
    public abstract void sound();
}

class Dog extends Animal {
    public Dog(String name) { super(name); }

    @Override
    public void sound() { System.out.println("멍멍"); }
}

class Cat extends Animal {
    public Cat(String name) { super(name); }

    @Override
    public void sound() { System.out.println("야옹"); }
}

함께 사용하는 경우

// 추상 클래스로 공통 기반 정의 + 인터페이스로 능력 추가
abstract class Animal {
    protected String name;
    public abstract void sound();
}

interface Trainable {
    void train();  // 훈련 가능한 동물만 구현
}

class Dog extends Animal implements Trainable {
    public Dog(String name) { this.name = name; }

    @Override
    public void sound() { System.out.println("멍멍"); }

    @Override
    public void train() { System.out.println("앉아!"); }
}

class Cat extends Animal {  // 훈련 불가 → Trainable 미구현
    public Cat(String name) { this.name = name; }

    @Override
    public void sound() { System.out.println("야옹"); }
}

선택 기준

"IS-A" 관계인가?          → 추상 클래스
  Dog is an Animal O

"CAN-DO" 관계인가?         → 인터페이스
  Dog can be Trained O

공통 필드/구현이 필요한가?  → 추상 클래스
다중 상속이 필요한가?       → 인터페이스

Java 8 이후 - default 메서드

// Java 8부터 인터페이스에 구현 메서드 추가 가능
interface Flyable {
    void fly();  // 추상 메서드

    default void land() {  // 구현 메서드 (선택적 오버라이드)
        System.out.println("착륙");
    }
}
// → 추상 클래스와 차이가 줄었지만
//   다중 구현 불가, 필드/생성자 불가 차이는 여전히 존재

실무에서는 인터페이스를 우선 고려하고, 공통 필드나 구현 공유가 필요할 때 추상 클래스를 사용합니다. Spring의 Repository, Service 등도 인터페이스 기반 설계를 따릅니다.

CSLOG에서 보기