Java에서 추상 클래스와 인터페이스는 둘 다 객체지향 프로그래밍에서 중요한 역할을 합니다. 하지만 이 두 가지는 역할과 사용 방법에서 차이가 있습니다.
extends
키워드를 사용)abstract class Animal {
String name; // 필드 선언
// 추상 메소드
abstract void sound();
// 구현된 메소드
void eat() {
System.out.println(name + " is eating.");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Bark");
}
}
• 다중 상속이 가능합니다. 즉, 여러 인터페이스를 동시에 구현할 수 있습니다.
• 변수를 가질 수 없습니다. 하지만 상수를 선언할 수 있습니다. (final 변수만 가능)
• 모든 메소드는 선언부만 존재하며, 실제 구현은 없고, 구현 클래스에서 모든 메소드를 오버라이딩(override) 해야 합니다.
• implements 키워드를 사용해 인터페이스를 구현합니다.
interface Animal {
// 추상 메소드
void sound();
// 자바 8 이후부터는 default 메소드 가능
default void sleep() {
System.out.println("Sleeping...");
}
}
class Cat implements Animal {
@Override
public void sound() {
System.out.println("Meow");
}
}
특징 | 추상 클래스 (abstract class) | 인터페이스 (interface) |
---|---|---|
상속 | 단일 상속만 가능 | 다중 상속 가능 |
변수 | 인스턴스 변수와 필드를 가질 수 있음 | 상수만 가질 수 있음 (final 변수) |
메소드 | 구현된 메소드를 포함할 수 있음 | 모든 메소드는 기본적으로 추상적임 |
접근 제한자 | 다양한 접근 제한자 사용 가능 | public 메소드만 가능 |
상속 키워드 | extends 키워드 사용 | implements 키워드 사용 |
Java 8 이후 변화 | - | default 메소드, static 메소드 사용 가능 |
Java 8부터는 인터페이스가 추상 클래스의 일부 기능을 흡수하기 시작했습니다.
• default 메소드: 인터페이스에서도 구현된 메소드를 가질 수 있게 되었습니다.
• static 메소드: 인터페이스 내에 정적 메소드도 선언할 수 있습니다.
또한 Java 9부터는 private 메소드도 인터페이스에서 사용할 수 있게 되어, 더 유연한 인터페이스 설계가 가능해졌습니다.
추상 클래스는 상태(변수)와 일부 기능(구현된 메소드)를 포함할 수 있는 클래스 간의 계층 구조를 만드는 데 적합하고, 인터페이스는 다중 상속이 필요한 경우나, 특정 동작을 여러 클래스에 공유할 때 사용하는 것이 적합합니다.
Java 버전이 높아지면서 인터페이스는 점점 더 강력해지고 있으며, 추상 클래스와 인터페이스의 경계가 조금씩 좁아지고 있지만, 여전히 상속 방식과 용도에 따라 구분해서 사용해야 합니다.