본문 바로가기
Language/Java

[JAVA] Java 상속(Inheritance)을 사용하는 이유와 제한 사항: 효율적인 객체 지향 설계를 위한 가이드

by Papa Martino V 2026. 1. 15.
728x90

상속(Inheritance)을 사용하는 이유와 제한 사항
상속(Inheritance)을 사용하는 이유와 제한 사항

 

자바(Java) 언어의 4대 핵심 원칙 중 하나인 상속(Inheritance)은 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 기술입니다. 단순히 코드를 복사하고 붙여넣는 수준을 넘어, 클래스 간의 계층 구조를 형성함으로써 거대한 소프트웨어 시스템을 체계적으로 관리할 수 있게 해줍니다. 하지만 상속은 '양날의 검'과 같습니다. 잘못된 상속 설계는 오히려 코드의 결합도를 높이고 유연성을 떨어뜨리기 때문입니다. 오늘은 자바 개발자라면 반드시 알아야 할 상속의 목적과 실무적 제한 사항에 대해 깊이 있게 다루어 보겠습니다.


1. 왜 상속을 사용하는가? (주요 장점)

상속을 사용하는 근본적인 이유는 '재사용성''다형성'의 확보에 있습니다.

  • 코드의 재사용성 증대: 공통된 속성과 메서드를 부모 클래스(Parent Class)에 정의해 두면, 자식 클래스(Child Class)는 이를 그대로 물려받아 사용할 수 있습니다. 이는 개발 시간을 단축시키고 코드 양을 획기적으로 줄여줍니다.
  • 유지보수의 용이성: 공통 로직이 부모 클래스에 집중되어 있으므로, 버그 수정이나 기능 개선이 필요할 때 부모 클래스만 수정하면 모든 자식 클래스에 자동으로 반영됩니다.
  • 다형성(Polymorphism) 구현: 부모 타입의 참조 변수로 자식 인스턴스를 참조할 수 있게 함으로써, 객체를 다루는 방식에 유연함을 부여합니다.
  • 분류의 체계화: 복잡한 도메인 모델을 계층화하여 논리적인 구조로 표현할 수 있습니다.

2. Java 상속의 핵심 제한 사항

자바는 언어 설계 단계부터 상속으로 인한 혼란을 방지하기 위해 몇 가지 엄격한 규칙을 적용하고 있습니다.

① 단일 상속(Single Inheritance) 원칙

자바는 클래스 간의 다중 상속을 지원하지 않습니다. 즉, 하나의 클래스는 오직 하나의 부모 클래스만 가질 수 있습니다. 이는 여러 부모로부터 동일한 이름의 메서드를 상속받을 때 발생하는 '다이아몬드 문제(Diamond Problem)'를 원천 차단하기 위함입니다.

② final 키워드의 제약

클래스에 final이 붙으면 더 이상 상속이 불가능하며, 메서드에 final이 붙으면 자식 클래스에서 오버라이딩(재정의)할 수 없습니다. 보안이나 설계 의도상 확장을 막아야 할 때 사용됩니다.

③ private 멤버의 접근 불가

부모 클래스의 필드나 메서드가 private으로 선언되어 있다면, 자식 클래스라도 직접 접근할 수 없습니다. 반드시 public이나 protected 또는 getter/setter를 통해 접근해야 합니다.


3. 상속(Inheritance) vs 포함(Composition)

실무에서는 "상속보다는 포함을 사용하라"는 격언이 있을 정도로 두 개념의 선택이 중요합니다. 아래 표를 통해 비교해 보겠습니다.

구분 상속 (Inheritance) 포함 (Composition)
관계 정의 is-a 관계 (~은 ~이다) has-a 관계 (~은 ~을 가졌다)
결합도 강한 결합 (부모 변경 시 자식 영향) 약한 결합 (독립적인 객체 조립)
유연성 낮음 (컴파일 시점에 결정) 높음 (실행 시점에 객체 교체 가능)
코드 예시 class Dog extends Animal class Car { Engine e; }

4. 상속을 올바르게 사용하는 방법

  1. 진정한 is-a 관계인지 확인: "사람은 생물이다"처럼 논리적으로 완벽하게 성립할 때만 상속을 사용하세요.
  2. 변경 가능성을 고려: 부모 클래스의 내부 구현이 바뀌었을 때 자식 클래스가 오작동할 위험(깨지기 쉬운 기반 클래스 문제)이 있다면 포함 관계를 고려하세요.
  3. 추상 클래스 활용: 구체적인 구현보다는 abstract class를 통해 공통 규격(Interface와 유사한 역할)을 상속받도록 설계하는 것이 안전합니다.

5. 결론

Java의 상속은 강력한 도구이지만, 오용할 경우 시스템 전체의 복잡도를 높이는 원인이 됩니다. 단일 상속이라는 제약 조건 아래에서 재사용성논리적 계층 구조를 확보하되, 불필요한 결합도를 피하기 위해 포함(Composition)과의 균형을 맞추는 것이 핵심입니다. 효율적인 상속 설계는 단순히 코드를 줄이는 것이 아니라, 변화에 유연하게 대응할 수 있는 아키텍처를 만드는 과정임을 명심해야 합니다.


내용 출처 및 참고 문헌

  • Oracle Java SE Documentation: Inheritance (The Java™ Tutorials)
  • Joshua Bloch, Effective Java 3rd Edition (아이템 18: 상속보다는 컴포지션을 사용하라)
  • Kathy Sierra, Bert Bates, Head First Java, O'Reilly Media



728x90