들어가며
Java에서 "메서드인데 내용이 없다"는 게 무슨 뜻일까요?
추상 메서드는 선언만 있고 구현부가 없는 메서드입니다.
이 글에서는 추상 메서드가 무엇인지, 왜 사용하는지 코드와 함께 정리해보겠습니다.
추상 메서드란?
추상 메서드는 선언부만 있고 구현부(중괄호 {})가 없는 메서드입니다.abstract 키워드를 붙여서 정의하며, 세미콜론(;)으로 끝납니다.
// 일반 메서드 - 구현부 있음
public void sound() {
System.out.println("동물 소리");
}
// 추상 메서드 - 구현부 없음
public abstract void sound();
"무슨 동작을 해야 하는지"는 정해두되, 실제로 어떻게 동작할지는 자식 클래스에서 구현하도록 강제하는 방식입니다.
추상 클래스(Abstract Class)란?
추상 메서드는 반드시 추상 클래스 안에 있어야 합니다.
추상 클래스는 abstract 키워드를 붙인 클래스로, 직접 객체를 생성할 수 없습니다.
abstract class Animal {
String name;
// 추상 메서드 - 구현 없음
public abstract void sound();
// 일반 메서드 - 구현 있음
public void eat() {
System.out.println(name + "이(가) 먹습니다.");
}
}
추상 클래스는 일반 메서드와 추상 메서드를 함께 가질 수 있습니다.
자식 클래스에서 반드시 구현해야 한다
추상 메서드를 상속받은 자식 클래스는 반드시 해당 메서드를 오버라이딩(구현) 해야 합니다.
구현하지 않으면 컴파일 오류가 발생합니다.
// 올바른 구현
class Dog extends Animal {
@Override
public void sound() {
System.out.println("멍멍"); // 반드시 구현
}
}
class Cat extends Animal {
@Override
public void sound() {
System.out.println("야옹"); // 반드시 구현
}
}
// 구현하지 않으면 컴파일 오류
class Bird extends Animal {
// sound() 구현 안 함 → 오류 발생!
}
객체 생성 불가
추상 클래스는 직접 객체를 생성할 수 없습니다.
반드시 자식 클래스를 통해 객체를 생성해야 합니다.
Animal animal = new Animal(); // 컴파일 오류! 추상 클래스는 객체 생성 불가
Animal dog = new Dog(); // 업캐스팅으로 사용 가능
dog.sound(); // "멍멍"
dog.eat(); // "null이(가) 먹습니다."
추상 클래스 vs 인터페이스
추상 클래스와 비슷한 개념으로 인터페이스가 있습니다.
| 항목 | 추상 클래스 | 인터페이스 |
|---|---|---|
| 키워드 | abstract class |
interface |
| 상속 키워드 | extends |
implements |
| 다중 상속 | 불가 (단일 상속) | 가능 |
| 일반 메서드 | 가질 수 있음 | default 키워드 필요 |
| 필드 | 가질 수 있음 | 상수만 가능 |
| 사용 목적 | 공통 기능 + 강제 구현 | 기능 규격 정의 |
// 추상 클래스 - 공통 기능 포함
abstract class Shape {
String color;
public abstract double area(); // 강제 구현
public void printColor() { // 공통 기능
System.out.println("색상: " + color);
}
}
// 인터페이스 - 규격만 정의
interface Drawable {
void draw(); // 구현 강제
}
실전 예시
추상 클래스는 "공통 구조는 같지만, 세부 동작은 각자 다르게 구현해야 할 때" 유용합니다.
abstract class Payment {
int amount;
// 공통 로직 - 결제 전 잔액 확인
public void validate() {
if (amount <= 0) {
throw new IllegalArgumentException("결제 금액이 올바르지 않습니다.");
}
}
// 추상 메서드 - 결제 방식은 자식이 구현
public abstract void pay();
}
class CardPayment extends Payment {
@Override
public void pay() {
validate();
System.out.println("카드로 " + amount + "원 결제");
}
}
class KakaoPayment extends Payment {
@Override
public void pay() {
validate();
System.out.println("카카오페이로 " + amount + "원 결제");
}
}
validate()처럼 공통 로직은 부모에서 관리하고, 결제 방식(pay())은 자식이 각자 구현합니다.
새로운 결제 수단이 추가되어도 Payment를 상속해 pay()만 구현하면 됩니다.
정리
- 추상 메서드는 선언부만 있고 구현부가 없는 메서드이며,
abstract키워드를 붙인다. - 추상 메서드는 반드시 추상 클래스 안에 있어야 한다.
- 추상 클래스를 상속받은 자식 클래스는 추상 메서드를 반드시 구현해야 한다.
- 추상 클래스는 직접 객체를 생성할 수 없고, 자식 클래스를 통해서만 사용할 수 있다.
- 공통 기능은 부모에서 관리하고, 세부 구현은 자식에게 맡기는 구조로 유지보수성과 확장성을 높인다.
'-- 오늘 있었던 개발 일기' 카테고리의 다른 글
| 상대경로와 절대경로 (0) | 2026.04.04 |
|---|---|
| 스트림(Stream)이란? - 입출력과 병렬처리 (0) | 2026.04.02 |
| 객체지향 프로그래밍(OOP)이란? (0) | 2026.03.19 |
| 참조 타입(Reference Type)이란? (0) | 2026.03.14 |
| 브라우저 렌더링 원리 (0) | 2026.02.20 |