JAVA (9) - 추상 클래스 vs 인터페이스
1. 개요
자바에서 추상 클래스(Abstract Class)와 인터페이스(Interface)는 모두 객체 지향 프로그래밍의 핵심 개념인 추상화(Abstraction)를 구현하기 위한 장치이다. 두 개념 모두 하위 클래스에서 반드시 구현해야 하는 메서드를 정의하여 코드의 규격을 강제하고 다형성을 확보하는 역할을 한다. 그러나 선언 방식과 설계 목적, 메모리 및 다중 상속의 허용 여부 등에서 명확한 차이가 존재한다.
2. 추상 클래스 (Abstract Class)
추상 클래스는 미완성된 설계도에 비유할 수 있으며, abstract 키워드를 사용해 선언한다. 하나 이상의 추상 메서드(구현부가 없는 메서드)를 포함할 수 있으며, 일반 클래스처럼 필드(변수)와 일반 메서드, 생성자도 가질 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public abstract class Animal {
private String name; // 일반 필드
public Animal(String name) { // 생성자
this.name = name;
}
public void sleep() { // 일반 메서드
System.out.println(name + "이(가) 잠을 잔다.");
}
public abstract void makeSound(); // 추상 메서드 (자식 클래스에서 반드시 구현)
}
- 인스턴스화 불가: 미완성된 클래스이므로
new Animal()과 같이 직접 객체를 생성할 수 없다. - 단일 상속: 자바의 클래스 상속 구조를 따르므로, 자식 클래스는 오직 하나의 추상 클래스만
extends할 수 있다. - 목적: 연관성이 높은 클래스들 간의 공통된 상태(필드)와 행위(메서드)를 공유하고 재사용할 때 사용한다.
3. 인터페이스 (Interface)
인터페이스는 극단적으로 추상화된 대표적인 밑그림에 비유할 수 있으며, interface 키워드를 사용해 선언한다. 기본적으로 모든 필드는 public static final(상수)이며, 모든 메서드는 public abstract(추상 메서드)로 동작한다. (Java 8 이후부터는 default 메서드와 static 메서드 구현이 가능하다.)
1
2
3
4
5
6
7
8
public interface Swimmable {
void swim(); // public abstract 생략 가능
}
public interface Flyable {
void fly();
}
1
2
3
4
5
6
7
8
9
10
11
12
public class Duck implements Swimmable, Flyable {
@Override
public void swim() {
System.out.println("오리가 수영을 한다.");
}
@Override
public void fly() {
System.out.println("오리가 날아간다.");
}
}
- 다중 구현 가능: 클래스는 여러 개의 인터페이스를 동시에
implements할 수 있다. - 상태 미보유: 객체의 상태를 나타내는 일반 인스턴스 필드를 가질 수 없다.
- 목적: 서로 다른 클래스 계층 구조를 가진 객체들에 공통된 행위 규격(접점)을 부여할 때 사용한다.
4. 추상 클래스 vs 인터페이스 주요 차점 비교
| 구분 | 추상 클래스 (Abstract Class) | 인터페이스 (Interface) |
|---|---|---|
| 선언 키워드 | abstract class | interface |
| 상속/구현 키워드 | extends | implements |
| 다중 지원 여부 | 단일 상속만 가능 | 다중 구현 가능 |
| 필드 (변수) | 일반 변수, 상수 모두 가능 | public static final (상수만 가능) |
| 생성자 | 생성자 존재 가능 | 생성자 존재 불가 |
| 메서드 | 추상 메서드 + 일반 구현 메서드 | 추상 메서드 (Java 8 이후 default, static 메서드 가능) |
| 핵심 목적 | 공통된 기능의 재사용 및 확장 (is-a 관계) | 동일한 행위의 규격 및 계약 강제 (can-do 관계) |
5. 상황별 선택 기준
두 방식 모두 하위 클래스의 메서드 구현을 강제하지만, 설계하는 목적에 따라 선택이 달라진다.
추상 클래스를 사용하는 경우 (is-a 관계):
- 명확한 계층 구조가 형성되고, 부모-자식 간에 긴밀한 연관성이 있을 때 사용한다.
- 하위 클래스들이 공통으로 사용하는 상태(필드)나 구현된 일반 메서드가 많을 때 유용하다.
인터페이스를 사용하는 경우 (can-do 관계):
- 부모-자식 관계와 관계없이 특정 기능(행위)만을 여러 클래스에 적용하고 싶을 때 사용한다.
- 다중 상속 효과를 내어 객체 간 결합도를 낮추고 유연한 확장성(디자인 패턴, DI 등)을 확보하고자 할 때 유용하다.
6. 정리
추상 클래스와 인터페이스는 모두 자바에서 추상화를 구현하는 중요한 도구이다. 추상 클래스는 ‘무엇인가(is-a)’에 집중하여 공통 상태와 기능을 상속을 통해 확장 및 재사용하는 데 목적이 있다.
인터페이스는 ‘무엇을 할 수 있는가(can-do)’에 집중하여 다중 구현을 통해 클래스의 행위 규격을 표준화하는 데 목적이 있다.