Java에서 abstract class와 interface는 둘 다 **추상화(abstraction)**를 위한 수단이지만, 설계 목적과 사용 방식에 중요한 차이가 있습니다. 아래에 그 차이점을 정리해 드릴게요.
✅ 공통점
- 둘 다 인스턴스화할 수 없음
- 둘 다 메서드 시그니처만 선언하고, 구현은 하위 클래스(또는 구현 클래스)에서 담당
- 둘 다 **다형성(polymorphism)**을 위한 수단
🔍 주요 차이점
| 항목 | abstract class |
interface |
|---|---|---|
| 키워드 | abstract class ClassName |
interface InterfaceName |
| 다중 상속 | 불가 (단일 상속만 가능) | 가능 (여러 인터페이스 구현 가능) |
| 생성자 | 생성자 정의 가능 | 생성자 없음 |
| 필드 | 인스턴스 변수, 정적 변수 가능 | public static final 상수만 선언 가능 (Java 8 이전 기준) |
| 메서드 구현 | 일부 메서드 구현 가능 | Java 8부터는 default, static 메서드 구현 가능 |
| 접근 제어자 | 다양한 접근 제어자(private, protected, public) 사용 가능 |
모든 메서드는 기본적으로 public abstract (Java 9 이후 private 메서드도 가능) |
| 목적 | “IS-A” 관계 (상속 기반의 계층화) | 기능 정의용, 계약 기반 구조 (다형성, 플러그인) |
✨ Java 8+ 이후 달라진 점
- Java 8부터 인터페이스에
default메서드와static메서드 추가 가능interface Vehicle { default void start() { System.out.println("Starting..."); } } - Java 9부터는
private메서드도 인터페이스 내부에서 선언 가능
✅ 언제 어떤 걸 써야 할까?
-
abstract class가 적합한 경우:- 여러 서브클래스가 공통 구현을 공유해야 할 때
- **상태(state)**를 가지는 필드가 필요할 때
-
interface가 적합한 경우:- 서로 다른 계층이나 클래스가 동일한 기능을 구현해야 할 때
- 다중 상속이 필요한 경우
- 설계 유연성을 확보하고 싶을 때
예시 비교
abstract class Animal {
String name;
void eat() {
System.out.println(name + " eats");
}
abstract void sound();
}
interface Flyable {
void fly();
}
필요하면 abstract class와 interface를 함께 사용할 수도 있어요.
예: class Bird extends Animal implements Flyable