Interface와 Abstract Class

mongBrown·2026년 4월 12일

interface와 abstract class, 뭘 써야 하는가

새 기능의 뼈대를 설계할 때 두 가지 선택지가 생긴다. interface와 abstract class다. 겉보기엔 둘 다 "완성되지 않은 것을 강제하는 구조"처럼 보이지만, 목적이 다르다.


interface — 역할 약속

interface는 "이 기능을 할 수 있다"는 약속이다. 구현 방식은 각 클래스가 결정하고, interface는 어떤 메서드를 반드시 가져야 하는지만 정의한다.

interface Runnable {
    void run(); // 구현 방식은 각 클래스에서 결정
}

여러 개를 동시에 구현할 수 있다는 게 핵심 특성이다. Dog가 달릴 수도 있고 비교도 가능하게 만들려면 두 interface를 함께 implements하면 된다.

class Dog implements Runnable, Comparable<Dog> { ... }

단, interface에서 변수를 선언하면 자동으로 public static final이 붙는다. interface는 인스턴스를 직접 만들지 않기 때문에, 변수가 어느 시점에 초기화될지 보장할 수 없다. 그래서 컴파일러가 강제로 상수로 만든다.

interface Counter {
    int count = 0; // 실제로는 public static final int count = 0;
}

이 말은 Counter를 구현한 클래스 10개가 있어도 모두 같은 count를 공유한다는 뜻이다. 인스턴스마다 독립적인 상태를 가질 수 없다.


abstract class — 공통 뼈대

abstract class는 "이 계열이다"라는 공통 구조다. 자식 클래스들이 공유하는 상태와 동작을 하나의 부모로 묶어두는 방식이다.

abstract class Animal {
    private String name; // 인스턴스마다 독립적으로 존재

    public Animal(String name) { this.name = name; }
    public String getName() { return name; }

    abstract void sound(); // 각 자식이 구현
}

인스턴스 변수를 가질 수 있고, 생성자를 통해 초기화할 수 있다. 자식 클래스들이 각자의 name을 가지면서 조회 로직은 부모에서 공통으로 처리된다.

extends로 하나만 상속할 수 있다. Dog extends Animal, Pet은 불가능하다.


Java 8 default method가 생기면서 달라진 것

Java 8에서 interface에 default method가 추가됐다. 이전까지는 abstract class만 기본 구현을 제공할 수 있었는데, interface도 가능해진 것이다.

interface Greeter {
    void greet(String name);

    default void greetAll(List<String> names) { // Java 8~
        names.forEach(this::greet);
    }
}

Java 9에서는 private method까지 추가됐다. interface 내부에서만 쓰는 공통 로직을 분리할 수 있다.

이 변화로 "그냥 다 interface로 하면 안 되나?"는 생각이 들 수 있다. 메서드 구현까지 가능해졌으니 abstract class 대신 쓸 수 있을 것 같지만, 인스턴스 상태 문제는 해결되지 않았다.


그래서 언제 뭘 쓰는가

공통으로 관리해야 할 인스턴스 상태가 있는지 없는지가 기준이다.

Comparable, Iterable, Runnable은 계열이나 상태와 무관하게 어떤 클래스든 구현할 수 있는 역할이다. interface가 맞다.

HttpServlet, AbstractList처럼 내부 상태와 공통 동작을 함께 묶어야 하는 경우는 abstract class가 맞다. 상태를 공유해야 하는 구조라면 interface로는 애초에 해결이 안 된다.

다중 구현이 가능한 interface가 유리한 경우가 더 많다. abstract class는 상태 공유가 필요할 때만 선택한다.

profile
화이팅!

0개의 댓글