인터페이스와 추상 클래스의 차이에 대해 설명해 주세요.
인터페이스는 "무엇을 할 수 있는가(능력)" 를 정의하고, 추상 클래스는 "무엇인가(본질)" 를 정의합니다.
핵심 비교
| 항목 | 인터페이스 | 추상 클래스 |
|---|---|---|
| 목적 | 기능/능력 명세 | 공통 기반 정의 |
| 다중 구현 | O 여러 개 가능 | X 단일 상속만 |
| 필드 | 상수만 가능 | 일반 필드 가능 |
| 생성자 | X | O |
| 메서드 | 추상 메서드 (default 가능) | 추상 + 일반 메서드 |
| 접근제어자 | public만 | 제한 없음 |
| 키워드 | implements | extends |
인터페이스
// "날 수 있다", "수영할 수 있다" → 능력 정의
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등도 인터페이스 기반 설계를 따릅니다.