상속

AI
gemma-4-31b
작성자
익명
작성일
2026.07.18
조회수
19
버전
v2

📋 문서 버전

이 문서는 2개의 버전이 있습니다. 현재 최신 버전을 보고 있습니다.

상속

상속(Inheritance)은 객체지향래밍(Object-Oriented Programming,OP)의 핵심 개념 중 하나로, 기존 클래스의 속성과 메서드를 새로운 클래스가 그대로 물려받아 재사용하고 확장할 수 있도록 해 메커니즘. 이는 코드의 중복을 줄이고, 프로그램의 유지보수성과 확장성을 높이는 데 중요한 역할을 합니다.

개요

상속을 통해 개발자는 기존에 정의된 클래스(부모 클래스 또는 슈퍼클래스)의 기능을 새로운 클래스(자식 클래스 또는 서브클래스)에서 재사용할 수 있습니다. 자식 클래스는 부모 클래스의 모든 공개(public) 및 보호(protected) 멤버를 접근할 수 있으며, 필요에 따라 새로운 속성과 메서드를 추가하거나 기존 메서드를 오버라이딩(Overriding)하여 기능을 변경할 수 있습니다.

상속은 "is-a" 관계를 표현하는 데 적합합니다. 예를 들어, 자동차 클래스가 있고, 전기차 클래스가 자동차를 상속받는 경우, "전기차는 자동차이다"라는 의미를 자연스럽게 표현할 수 있습니다.


상속의 기본 구조

부모 클래스와 자식 클래스

  • 부모 클래스(Parent Class): 다른 클래스가 상속받는 원본 클래스. 기반 클래스(Base Class) 또는 슈퍼클래스(Superclass)라고도 부릅니다.
  • 자식 클래스(Child Class): 부모 클래스로부터 속성과 메서드를 상속받는 클래스. 파생 클래스(Derived Class) 또는 서브클래스(Subclass)라고도 합니다.

예시 코드 (Python 기준)

class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        return f"{self.name}이(가) 소리를 냅니다."

class Dog(Animal):  # Animal 클래스를 상속
    def speak(self):  # 메서드 오버라이딩
        return f"{self.name}이(가) 멍멍하고 짖습니다."

# 사용 예시
my_dog = Dog("바둑이")
print(my_dog.speak())  # 출력: 바둑이이(가) 멍멍하고 짖습니다.

위 코드에서 Dog 클래스는 Animal 클래스를 상속받아 name 속성과 speak() 메서드를 사용할 수 있으며, speak() 메서드를 오버라이딩하여 구체적인 동작을 정의하고 있습니다.


상속의 유형

상속은 언어와 설계에 따라 다양한 형태로 구현될 수 있습니다.

1. 단일 상속 (Single Inheritance)

한 클래스가 단 하나의 부모 클래스만을 상속받는 방식입니다. 대부분의 객체지향 언어에서 기본적으로 지원됩니다.

class Parent:
    pass

class Child(Parent):
    pass

2. 다중 상속 (Multiple Inheritance)

한 클래스가 두 개 이상의 부모 클래스를 동시에 상속받는 방식입니다. Python과 C++ 등 일부 언어에서 지원하지만, 다이아몬드 문제(Diamond Problem)와 같은 복잡성을 유발할 수 있습니다.

class A:
    def method(self):
        print("A의 메서드")

class B(A):
    pass

class C(A):
    def method(self):
        print("C의 메서드")

class D(B, C):  # 다중 상속
    pass

d = D()
d.method()  # 출력: "C의 메서드" (메서드 해석 순서: MRO)

Python은 MRO(Method Resolution Order)를 사용하여 다중 상속 시 메서드 호출 순서를 결정합니다.

3. 계층적 상속 (Hierarchical Inheritance)

한 부모 클래스가 여러 자식 클래스에 의해 상속되는 구조입니다.

 Animal:
    def eat(self):
        print("먹는다")

class Dog(Animal):
    def bark(self):
        print("짖는다")

class Cat(Animal):
    def meow(self):
        print("야옹한다")


상속의 장점

  • 코드 재사용성: 중복된 코드를 줄이고, 공통 기능을 한 곳에서 관리할 수 있습니다.
  • 확장성: 기존 클래스를 변경하지 않고 새로운 기능을 추가할 수 있습니다.
  • 유지보수성: 공통 로직이 한 클래스에 집중되어 있어 수정이 용이합니다.
  • 다형성 지원: 상속은 다형성(Polymorphism)을 구현하는 기초가 됩니다.

주의사항 및 한계

  • 과도한 상속은 복잡성 증가: 깊은 상속 계층은 코드 이해를 어렵게 만들 수 있습니다.
  • 결합도 증가: 자식 클래스는 부모 클래스에 강하게 결합되어 있어, 부모 클래스 변경 시 영향을 받을 수 있습니다.
  • 다중 상속의 위험성: 명확한 설계 없이 다중 상속을 사용하면 예측할 수 없는 동작이 발생할 수 있습니다.

이러한 문제를 피하기 위해, 현대 소프트웨어 설계에서는 "상속보다는 구성(Favor composition over inheritance)"이라는 원칙을 권장합니다.


관련 개념

  • 추상 클래스(Abstract Class): 인스턴스를 생성할 수 없고, 상속을 위해 설계된 클래스로, 일부 메서드는 구현 없이 정의됩니다.
  • 인터페이스(Interface): 메서드의 시그니처만 정의하고, 구현은 자식 클래스에서 완료하도록 강제하는 설계 방식 (Java, C# 등).
  • 오버라이딩(Overriding): 자식 클래스가 부모 클래스의 메서드를 재정의하는 것.
  • 오버로딩(Overloading): 같은 이름의 메서드를 매개변수로 구분하여 여러 개 정의하는 것 (Python은 기본적으로 미지원).

상속의 설계적 의미

상속은 단순한 코드의 재사용을 넘어, 객체 간의 계층 구조(Hierarchy)를 형성하는 설계 도구입니다. 이를 통해 개발자는 일반적인 개념(부모 클래스)에서 구체적인 개념(자식 클래스)으로 이어지는 추상화 단계를 구축할 수 있으며, 이는 복잡한 도메인 모델을 체계적으로 분류하고 데이터의 추상화 수준을 높여 소프트웨어의 논리적 구조를 명확히 하는 데 기여합니다.

리스코프 치환 원칙 (LSP)

리스코프 치환 원칙(Liskov Substitution Principle, LSP)은 상속 관계가 성립하기 위한 논리적 조건으로, "자식 클래스는 언제나 자신의 부모 클래스를 대체할 수 있어야 한다"는 원칙입니다. 즉, 부모 클래스 타입의 객체를 사용하는 기존 코드에서 이를 자식 클래스 객체로 바꾸어도 프로그램의 정밀성과 동작이 변하지 않아야 합니다.

LSP 위반 사례와 해결

가장 대표적인 위반 사례는 '정사각형-직사각형 문제'입니다. 수학적으로 정사각형은 직사각형의 일종이지만, 프로그램 설계상으로는 다를 수 있습니다.

[위반 코드]

class Rectangle:
    def set_width(self, w): self.width = w
    def set_height(self, h): self.height = h
    def get_area(self): return self.width * self.height

class Square(Rectangle):
    def set_width(self, w):
        self.width = w
        self.height = w  # 정사각형 유지를 위해 높이도 함께 변경 (LSP 위반)
    def set_height(self, h):
        self.width = h
        self.height = h
위 코드에서 Rectangle을 기대하고 작성된 함수에 Square 객체를 전달하면, 너비만 바꿨는데 높이까지 바뀌어 계산 결과가 예상과 달라지는 문제가 발생합니다.

[해결 코드: 인터페이스 분리 및 구성] 상속 관계를 강제하기보다 공통 인터페이스(Shape)를 정의하거나 구성을 사용합니다.

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def get_area(self): pass

class Rectangle(Shape):
    def __init__(self, w, h):
        self.w, self.h = w, h
    def get_area(self): return self.w * self.h

class Square(Shape):
    def __init__(self, side):
        self.side = side
    def get_area(self): return self.side ** 2

상속과 구성의 비교

"상속보다는 구성(Composition)을 사용하라"는 원칙은 객체 간의 관계를 설정할 때 강한 결합(상속)보다 유연한 결합(구성)을 지향하라는 의미입니다.

구분 상속 (Inheritance) 구성 (Composition)
관계 정의 is-a (~은 ~이다) has-a (~은 ~을 가진다)
결합도 강한 결합 (Tight Coupling) 느슨한 결합 (Loose Coupling)
변경 영향 부모 클래스 변경 시 자식에게 전파됨 내부 객체 변경 시 캡슐화로 영향 최소화
결정 시점 컴파일 타임 (정적) 런타임 (동적)
사용 사례 명확한 계층 구조, 다형성 필요 시 기능의 조합, 유연한 교체 필요 시

다이아몬드 문제의 상세 분석

다이아몬드 문제(Diamond Problem)는 한 클래스가 두 개의 부모 클래스를 상속받고, 그 두 부모 클래스가 다시 하나의 공통 조상 클래스를 상속받을 때 발생합니다. 이때 자식 클래스에서 조상 클래스의 메서드를 호출하면, 어떤 부모의 경로를 통해 메서드를 실행해야 할지 모호해지는 상황을 말합니다.

언어별 해결 방식의 차이

  • Python: MRO(Method Resolution Order) 알고리즘(C3 Linearization)을 사용하여 탐색 순서를 선형적으로 결정합니다. ClassName.mro()를 통해 호출 순서를 명시적으로 확인할 수 있습니다.
  • C++: 가상 상속(Virtual Inheritance)을 사용합니다. class B : virtual public A와 같이 선언하여, 공통 조상 클래스의 인스턴스가 단 하나만 생성되도록 보장함으로써 중복 문제를 해결합니다.
  • Java / C#: 클래스의 다중 상속을 원천적으로 금지합니다. 대신 인터페이스(Interface)의 다중 구현을 허용하여 구조적 모호성을 제거합니다. (Java 8 이후의 default method 충돌은 개발자가 직접 오버라이딩하여 해결하도록 강제함)

취약한 기반 클래스 문제 (Fragile Base Class Problem)

상속으로 인한 결합도 증가의 구체적인 위험성은 취약한 기반 클래스 문제로 나타납니다. 이는 부모 클래스(기반 클래스)의 내부 구현을 변경했을 때, 이를 상속받은 수많은 자식 클래스들이 예상치 못한 방식으로 오작동하거나 함께 수정되어야 하는 현상을 말합니다.

특히 부모 클래스의 메서드가 내부적으로 다른 메서드를 호출하는 구조일 때, 자식 클래스에서 해당 메서드를 오버라이딩하면 부모의 내부 로직 흐름이 깨지면서 시스템 전체의 안정성이 저하되는 기술적 위험을 초래합니다.

참고 자료

  • Gamma, E., et al. (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley.
  • Python 공식 문서 - Inheritance
  • Oracle Java Tutorials - Interfaces and Inheritance

상속은 객체지향 설계의 기초이지만, 적절한 설계 원칙과 함께 사용되어야 효과적인 소프트웨어 아키텍처를 구축할 수 있습니다.

AI 생성 콘텐츠 안내

이 문서는 AI 모델(gemma-4-31b)에 의해 생성된 콘텐츠입니다.

주의사항: AI가 생성한 내용은 부정확하거나 편향된 정보를 포함할 수 있습니다. 중요한 결정을 내리기 전에 반드시 신뢰할 수 있는 출처를 통해 정보를 확인하시기 바랍니다.

이 AI 생성 콘텐츠가 도움이 되었나요?