[JAVA]추상 클래스와 인터페이스 차이

[JAVA] 추상 클래스와 인터페이스 차이

자바에서 다형성을 공부하다 보면 다음으로 꼭 등장하는 개념이 추상 클래스인터페이스입니다.

저는 처음에 이 둘을 보고 "둘 다 상속 비슷한데 뭐가 다른 거지?" 라는 생각이 들었습니다

그래서 이번 글에서는 문법 비교보다는 실제 코드와 출력 결과를 통해 차이를 정리해보려고 합니다.


1. 추상 클래스란?

추상 클래스는 일부는 구현되어 있고, 일부는 미완성인 클래스입니다.

공통 기능은 미리 만들어두고, 상속받는 클래스가 꼭 구현해야 할 메서드는 추상 메서드로 남겨둡니다.


abstract class Animal {

    void breathe() {
        System.out.println("숨을 쉽니다.");
    }

    abstract void sound();
}

이제 이 추상 클래스를 상속받는 클래스를 만들어보겠습니다.


class Dog extends Animal {

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

메인 메서드에서 실행해보겠습니다.


public class Main {
    public static void main(String[] args) {

        Animal animal = new Dog();
        animal.breathe();
        animal.sound();
    }
}

실행 결과 (Output)


숨을 쉽니다.
멍멍

추상 클래스는 일반 메서드 + 추상 메서드를 함께 가질 수 있다는 점이 특징입니다.


2. 인터페이스란?

인터페이스는 기능의 규칙(약속)만 정의하는 역할을 합니다.

"이 기능을 구현하려면 반드시 이런 메서드를 만들어라" 라고 강제하는 용도라고 이해했습니다.


interface Animal {

    void sound();
}

인터페이스를 구현하는 클래스입니다.


class Cat implements Animal {

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

실행 코드입니다.


public class Main {
    public static void main(String[] args) {

        Animal animal = new Cat();
        animal.sound();
    }
}

실행 결과 (Output)


야옹

인터페이스는 구현은 없고, 메서드 선언만 존재한다는 점이 가장 큰 차이입니다.


3. 추상 클래스 vs 인터페이스 차이

구분 추상 클래스 인터페이스
상속/구현 extends implements
메서드 일반 메서드 + 추상 메서드 추상 메서드만 (기본)
상속 개수 단일 상속 다중 구현 가능
용도 공통 기능 + 기본 구현 기능 규칙 정의

4. 언제 추상 클래스를 쓸까?

저는 추상 클래스를 "부모 역할이 확실할 때" 사용한다고 이해했습니다.

  • 공통 필드나 로직이 많은 경우
  • 강한 is-a 관계가 있는 경우
  • 기본 동작을 물려주고 싶은 경우

예를 들면 Animal → Dog, Cat 같은 관계입니다.


5. 언제 인터페이스를 쓸까?

인터페이스는 "이 기능을 할 수 있다"라는 개념에 더 가깝다고 느꼈습니다.

  • 클래스 간 관계가 느슨할 때
  • 여러 클래스에 같은 기능을 부여할 때
  • 다중 구현이 필요할 때

예를 들어 Flyable, Runnable 같은 역할 개념에 잘 어울립니다.


6. 초보자 입장에서 정리

처음에는 둘의 차이를 외우려고 했는데, 지금은 이렇게 정리하고 있습니다.

  • 추상 클래스: "부모 클래스"
  • 인터페이스: "기능 규칙"

완벽하게 이해하지 못해도, 다형성과 함께 예제를 여러 번 작성해보면 조금씩 감이 잡히는 것 같습니다.

이 개념은 나중에 스프링을 공부할 때 왜 인터페이스를 많이 쓰는지 이해하는 데도 큰 도움이 됩니다.