| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
Tags
- 템플릿 메서드 패턴
- 김영한
- Til
- 디자인 패턴
- redis
- 코드카타
- 트러블슈팅
- 토스
- 이펙티브 자바
- spring boot
- Spring Batch
- 스프링 배치
- 스케줄러
- DB
- java
- 자바
- 성능 개선
- 프로그래머스
- 스프링
- 로드밸런서
- 추상클래스
- 백엔드
- GoF 23
- 빌더 패턴
- 프록시 패턴
- 배치
- Spring
- Effective Java
- 계산기
- lv1
Archives
- Today
- Total
김코딩
둘 다 객체 못 만든다면서요? 그런데 왜 둘이나 있는 거죠?(인터페이스 VS 추상클래스) 본문
이번에는 추상클래스와 인터페이스의 차이점에 대해 이야기해보겠습니다.
추상클래스의 주요 특징
- 객체를 직접 생성할 수 없습니다.
new 키워드로 인스턴스를 만들면 컴파일 에러가 발생합니다. - 추상 메서드를 포함할 수 있으며,
추상클래스를 상속받은 자식 클래스는 이 추상 메서드를 반드시 오버라이딩해야 합니다. - 모든 메서드가 추상 메서드로만 구성된 클래스를
순수 추상 클래스(Pure Abstract Class) 라고 하며,
이 구조는 인터페이스와 매우 유사한 형태입니다.
인터페이스란?
인터페이스(Interface)는기능의 설계서 또는 규칙의 집합이라고 할 수 있습니다.
클래스에게"이 기능을 꼭 구현해!"라고 강제하는계약서 같은 존재입니다.
인터페이스 선언
public interface 인터페이스명 {
//public 상수 필드
//public 추상 메소드
//public 디폴트 메소드
//public 정적 메소드
//private 메소드
//private 정적 메소드
}
인터페이스는 순수 추상 메서드와 같지만 약간의 편의 기능이 추가되었습니다.
- 인터페이스는 원래 모든 메서드가 public abstract 였습니다.
메서드에 public abstract를 생략해도 되며, 생략하는 것이 일반적입니다. - 자바 8 이후부터는 default 메서드, static 메서드,
자바 9부터는 private 메서드도 선언 가능합니다. - 다중 구현(다중 상속)을 지원합니다.
→ 한 클래스가 여러 개의 인터페이스를 구현할 수 있습니다.
추상클래스 VS 인터페이스
| 구분 | 추상클래스 (abstract class) | 인터페이스 (interface) |
| 객체 생성 | 불가능 | 불가능 |
| 상속/구현 키워드 | extends (단일 상속만 가능) | implements (다중 구현 가능) |
| 다중 상속 | 안 됨 | 가능 |
| 필드 선언 | 일반 필드 선언 가능 | 모든 필드는 public static final (상수) |
| 메서드 선언 | 일반 메서드 + 추상 메서드 모두 가능 | 기본은 추상 메서드, Java 8 이후 default, static 메서드 가능 |
| 접근 제어자 | 자유롭게 설정 가능 (private, protected, etc.) | 모든 메서드는 기본적으로 public (생략 가능) |
| 생성자 | 가질 수 있음 (하지만 객체는 못 만듦) | 생성자 정의 불가능 |
| 용도 | 공통된 기능 제공 + 상속 구조 설계 | 기능 명세(규칙) 제공, 다형성의 극대화 |
| 자바 클래스 상속 | 클래스는 단 하나의 추상클래스만 상속 가능 | 클래스는 여러 인터페이스를 동시에 구현 가능 |
그런데 궁금하지 않으신가요?
“순수 추상 클래스와 인터페이스가 그렇게 비슷하다면,
굳이 인터페이스라는 개념이 또 나와야 할까요?”
순수 추상 클래스는 인터페이스와 거의 동일한 기능을 제공합니다.
실제로 모든 메서드가 추상 메서드로만 구성된 추상 클래스는 인터페이스처럼 동작합니다.
하지만 이 구조에는 잠재적인 문제가 존재합니다.
미래에 누군가 이 클래스에 일반 메서드를 추가하게 된다면,
더 이상 "순수 추상 클래스"가 아니게 됩니다.
또한, 인터페이스는 다중 상속이 가능하기 때문에
클래스 구조를 유연하게 설계할 수 있다는 점에서도 차별점이 있습니다.
그러면 언제 무엇을 써야할까요?
사실 추상 클래스와 인터페이스 모두 "공통 기능을 정의하고 강제하는 도구"입니다.
하지만 사용하는 목적과 상황에 따라 선택 기준이 달라집니다.
추상 클래스가 더 적합한 경우
- 공통된 상태(필드)와 동작(일반 메서드)을 함께 제공하고 싶을 때
- 상속받는 클래스들 사이에 "is-a 관계"가 있을 때
예: Animal → Dog, Cat - 한 클래스만 상속하면 충분할 때 (단일 상속 구조)
abstract class Animal {
String name;
void breathe() {
System.out.println("숨을 쉰다");
}
abstract void sound();
}
인터페이스가 더 적합한 경우
- 클래스에 특정 기능을 "강제"하고 싶을 때
- 여러 클래스가 서로 다른 구조지만 같은 기능을 가져야 할 때
- 이미 다른 클래스를 상속받고 있어서 다중 상속이 필요할 때
interface Flyable {
void fly();
}
interface Swimmable {
void swim();
}
class Duck extends Animal implements Flyable, Swimmable {
public void fly() { ... }
public void swim() { ... }
}
한눈에 비교
| 공통 필드와 기능을 함께 제공해야 함 | 추상 클래스 |
| 여러 기능을 조합해야 함 | 인터페이스 |
| 다중 상속이 필요함 | 인터페이스 |
| 공통 부모 타입으로서 역할을 강조하고 싶음 | 추상 클래스 |
| 기능만 선언하고 구현은 위임하고 싶음 | 인터페이스 |
'TIL' 카테고리의 다른 글
| 일정 관리 API 프로젝트 회고 (0) | 2025.05.14 |
|---|---|
| Kiosk 프로젝트 회고 (3) | 2025.05.01 |
| 객체를 못 만드는 클래스가 있다고요? 그게 바로 추상클래스 (2) | 2025.04.23 |
| 계산기 Lv.3 (0) | 2025.04.22 |
| 이놈의 Enum, 그거 어떻게 쓰는건데? (0) | 2025.04.22 |