자바를 공부하면서 추상 클래스와 상속에 대해 자주 고민하게 된다. 처음에는 두 개념이 비슷해 보였지만, 학습을 하면서 객체 지향 설계에서 서로 다른 역할을 한다는 것을 알게 되었다. 이번 글에서는 추상 클래스와 상속이 각각 무엇인지 둘의 차이점에 대해 정리하고자 한다.
추상 클래스는 인스턴스화할 수 없는 클래스다. 직접 객체를 생성할 수 없고, 이를 상속받은 하위 클래스에서 구현되어야 한다. 추상 클래스는 추상 메서드(구현이 없는 메서드)와 일반 메서드(구현이 있는 메서드)를 모두 포함할 수 있다. 추상 메서드는 하위 클래스가 반드시 구현해야 하며, 일반 메서드는 모든 하위 클래스가 공유할 공통 기능을 정의한다.
추상 클래스는 주로 상속을 위한 템플릿 역할을 한다. 여러 하위 클래스가 공통 기능을 가지면서도, 세부적인 동작을 각 클래스가 다르게 구현할 필요가 있을 때 유용하다.
abstract class Animal {
// 추상 메서드
abstract void sound();
// 일반 메서드
void breathe() {
System.out.println("Breathing...");
}
}
이 코드에서 Animal 클래스는 추상 메서드 sound()와 일반 메서드 breathe()를 가진다. sound()는 구체적인 구현이 없고, 이를 상속받는 하위 클래스에서 정의해야 한다.
상속은 코드 재사용성을 높이기 위한 자바의 중요한 기능이다. 한 클래스가 다른 클래스의 속성과 메서드를 물려받는 개념으로, 상위 클래스와 하위 클래스 사이의 관계를 형성한다. 상속을 통해 하위 클래스는 상위 클래스의 모든 필드와 메서드를 물려받으며, 필요에 따라 메서드를 오버라이딩(재정의)할 수 있다.
자바는 단일 상속만 지원하므로, 한 클래스는 하나의 상위 클래스만 상속받을 수 있다. 하지만 상속을 통해 계층 구조를 형성하면 코드의 중복을 줄이고 유지보수를 쉽게 할 수 있다.
class Dog extends Animal {
@Override
void sound() {
System.out.println("Bark");
}
}
Dog 클래스는 Animal 클래스를 상속받아 sound() 메서드를 구현한다. 부모 클래스인 Animal의 breathe() 메서드를 그대로 사용할 수 있다.
추상 클래스와 상속은 모두 객체 지향 프로그래밍의 핵심 개념이지만, 목적과 사용 방식에서 차이가 있다.
추상 클래스가 적합한 경우
상속이 적합한 경우
추상 클래스와 상속은 자바에서 객체 지향 프로그래밍을 이해하고 설계할 때 반드시 알아야 할 개념이다. 추상 클래스는 공통적인 동작을 정의하면서, 세부적인 구현은 하위 클래스에 맡기고 싶을 때 유용하다. 상속은 부모 클래스의 기능을 재사용하거나 확장할 때 효과적이다. 이 두 개념을 잘 이해하고 적절히 활용하면, 더 효율적이고 유지보수가 쉬운 코드를 작성할 수 있다.