[Java] 자바의 추상 클래스 vs 인터페이스 완전 정복

2025. 10. 9. 17:04·Java

들어가며

자바를 공부하다 보면 “추상 클래스”와 “인터페이스”가 헷갈릴 때가 많습니다.
둘 다 추상화(Abstraction) 개념을 구현하는 방법이지만,
그 목적과 쓰임새는 분명히 다릅니다.

이번 글에서는 아래와 같은 차이와 예제를 완벽하게 정리해보겠습니다!

“둘은 어떤 차이가 있을까?”
“언제 추상 클래스를 쓰고, 언제 인터페이스를 써야 할까?”
를 예제와 함께 완벽하게 정리해보겠습니다.


추상화란?

추상화(Abstraction)는 복잡한 현실 세계를 단순화하는 과정입니다.
즉, 필요한 정보만 남기고 불필요한 세부사항은 숨기는 것이죠.

자바에서 추상화는 크게 두 가지 형태로 나타납니다:

  • 데이터 추상화 (Data Abstraction) → 데이터 구조를 숨김
  • 제어 추상화 (Control Abstraction) → 동작(로직)의 세부 구현을 숨김

그리고 추상 클래스와 인터페이스는 이 중 “제어 추상화”를 표현하는 대표적인 방법입니다.


추상 클래스 (abstract class)

“공통된 속성과 동작을 공유하되, 일부는 하위 클래스가 정의하도록 하는 클래스”

특징

  • abstract 키워드 사용
  • 상속(extends)을 통해 구현
  • 일반 메서드 + 추상 메서드 둘 다 가질 수 있음
  • 상태(멤버 변수) 를 가질 수 있음
  • 생성자 가짐
  • 단일 상속만 가능

예제

abstract class Payment {
    abstract void pay(int amount);

    void log(int amount) {
        System.out.println(amount + "원 결제 완료");
    }
}

class CardPayment extends Payment {
    @Override
    void pay(int amount) {
        System.out.println("카드로 " + amount + "원 결제");
        log(amount);
    }
}

class KakaoPay extends Payment {
    @Override
    void pay(int amount) {
        System.out.println("카카오페이로 " + amount + "원 결제");
        log(amount);
    }
}

→ 공통된 결제 로직(log)은 상속받고, 결제 방식(pay)만 다르게 구현.


 인터페이스 (interface)

“공통된 동작을 정의하는 규약(명세서)”

 특징

  • interface 키워드 사용
  • 구현(implements) 을 통해 구현
  • 원래는 오직 추상 메서드와 상수만 포함 가능했지만
    Java 8 이후 default, static 메서드,
    Java 9 이후 private 메서드도 가능
  • 다중 구현 가능

 예제

interface Notifier {
    void send(String message);
}

class EmailNotifier implements Notifier {
    public void send(String message) {
        System.out.println("이메일 발송: " + message);
    }
}

class SMSNotifier implements Notifier {
    public void send(String message) {
        System.out.println("문자 발송: " + message);
    }
}

public class Main {
    public static void main(String[] args) {
        Notifier n1 = new EmailNotifier();
        Notifier n2 = new SMSNotifier();

        n1.send("안녕하세요!");
        n2.send("오늘은 좋은 하루!");
    }
}

→ 서로 다른 클래스지만, 같은 인터페이스를 통해 동일한 동작 수행 가능!


 추상 클래스 vs 인터페이스 비교 정리

구분 추상 클래스 인터페이스

키워드 abstract class interface
상속 방식 extends (단일 상속) implements (다중 구현 가능)
구성 요소 변수, 생성자, 일반 + 추상 메서드 상수, 추상 메서드, default/static 메서드
상태(필드) 보유 가능 불가능 (상수만 가능)
생성자 있음 없음
목적 공통된 속성과 동작 제공 규약(계약) 제공
관계 표현 “A는 B의 일종이다 (is-a)” “A는 B의 기능을 가진다 (can-do)”
사용 예시 여러 클래스가 비슷한 구조를 가질 때 서로 다른 클래스가 같은 기능을 수행할 때

둘을 함께 쓰는 경우

실무에서는 종종 추상 클래스 + 인터페이스를 함께 사용합니다.

interface Authenticatable {
    boolean authenticate(String token);
}

abstract class User {
    String name;
    abstract void login();
}

class AdminUser extends User implements Authenticatable {
    void login() {
        System.out.println("관리자 로그인");
    }

    public boolean authenticate(String token) {
        return token.equals("admin-token");
    }
}

➡️ User는 공통 속성과 기본 틀을 제공,
➡️ Authenticatable은 인증 규약을 명시.
➡️ 둘을 조합하면 구조적 일관성과 유연성을 동시에 얻을 수 있음.

 

Java 8 이후 인터페이스가 강력해진 이유

인터페이스에 default 메서드가 추가된 이유는
기존 구현체들과의 하위 호환성 때문입니다.

예를 들어, 기존에 List 인터페이스에 새로운 기능을 추가하고 싶어도
모든 구현체(ArrayList, LinkedList 등)에 일일이 코드를 추가할 수 없었죠.
이 문제를 해결하기 위해 default 메서드가 생겼습니다.

interface Logger {
    default void log(String msg) {
        System.out.println("로그: " + msg);
    }
}

➡️ 인터페이스도 이제 “부분 구현”이 가능해지면서
추상 클래스와의 경계가 조금 흐려졌다는 점이 포인트입니다.


언제 어떤 걸 써야 할까?

상황별 추천하는 방법

여러 클래스가 공통 속성(필드)과 로직을 공유 추상 클래스
서로 다른 클래스들이 동일한 기능을 수행해야 함 인터페이스
다중 상속 구조가 필요함 인터페이스
기본 구현 + 확장성을 둘 다 원함 추상 클래스 + 인터페이스 조합

마무리

추상 클래스와 인터페이스는 둘 다 “추상화”를 구현하지만
목적이 다르다는 점이 핵심입니다.

  • 추상 클래스: 공통 기반 제공 (상속 중심)
  • 인터페이스: 행동 규약 제공 (다형성 중심)

둘을 제대로 구분하고 조합할 수 있다면,
코드의 재사용성·유연성·확장성이 눈에 띄게 올라갑니다.

 

 

'Java' 카테고리의 다른 글

[JAVA] 객체지향개념Ⅱ  (0) 2025.10.13
[Java] 문자열 처리 성능비교 - String vs StringBuilder vs StringBuffer  (0) 2025.10.11
[JAVA] 데이터 추상화 vs 제어 추상화  (0) 2025.10.09
[Java] 객체지향개념I  (0) 2025.10.08
[Java] 클래스 메소드(static 메소드) vs 인스턴스 메소드  (0) 2025.10.03
'Java' 카테고리의 다른 글
  • [JAVA] 객체지향개념Ⅱ
  • [Java] 문자열 처리 성능비교 - String vs StringBuilder vs StringBuffer
  • [JAVA] 데이터 추상화 vs 제어 추상화
  • [Java] 객체지향개념I
싹난 감자🥔🌱
싹난 감자🥔🌱
개발 블로그
  • 싹난 감자🥔🌱
    감자에 싹이나서 잎이나서
    싹난 감자🥔🌱
  • 전체
    오늘
    어제
    • 분류 전체보기 (43)
      • Spring (3)
      • Java (17)
      • LLM (1)
      • DevOps (4)
      • Algorithm (14)
        • 백준 (4)
        • 프로그래머스 (0)
        • 코드업 (10)
      • Computer Science (3)
        • Operating System (2)
        • Computer Architecture (1)
      • Trouble Shooting 🚀 (0)
      • 회고 & 성장기록 (1)
      • 설계 📐 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Java
    BufferedReader
    자바Scanner비교
    자바 입력
    자바성능
    비트
    배포
    docker
    Scanner
    2진수
    알고리즘입력
    자바BufferedReader
    2차원 배열
    구간합
    코딩테스트
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
싹난 감자🥔🌱
[Java] 자바의 추상 클래스 vs 인터페이스 완전 정복
상단으로

티스토리툴바