C.W.K.
Stream
Lesson 05 of 07 · published

상속, super(), 그리고 상속보다 합성

~22 min · inheritance, super, composition, subclass

Level 0호기심
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete

상속 — 복사 없이 확장

클래스가 다른 클래스 상속 가능 — class Dog(Animal):. 서브클래스가 부모의 모든 속성 + 메서드 받고, 추가 / override 가능. 잘 쓰면 "is-a" 관계 모델 — Dog *is an* Animal. 잘못 쓰면 동작 override 의 엉킨 실타래 — 아무도 못 따라가.

super() — 부모 버전 호출

메서드 override 할 때 종종 부모가 하는 거 + 자기 로직 추가하고 싶어. super().method(...) 가 부모 버전 호출. 가장 흔한 용도 — 서브클래스 __init__ 안의 super().__init__(...) — 부모가 자기 부분 init 하게 하고 자기 init.

메서드 해석 — 단일 상속 룰

단일 상속의 룰 단순 — Python 이 인스턴스 클래스 체크, 부모, 부모의 부모, ... object 까지. 첫 매치 이김. 다중 상속은 C3 linearization 알고리즘으로 복잡 — 다음 트랙. 지금은 단일 상속이 실세계 대부분 커버.

합성으로 가야 할 때

class Car(Engine): 짜고 있으면 멈춰. car *has-a* engine, *is-an* engine 아님. 맞는 모양 — self.engine = Engine(). 합성은 각 클래스가 한 책임에 집중하게, 교체 쉽게, 단편적 디자인이 만드는 깊은 상속 트리 회피. 현대 Python 스타일이 강하게 합성 선호.

원칙: "상속보다 합성." 상속은 관계가 진짜 "is-a" *그리고* 부모 동작을 확장하고 싶을 때 (모든 거 override 해서 커스터마이즈 X) 맞아. 아니면 — 합성. Pippa 의 어댑터들은 합성, 상속 X — 유일 상속은 streaming API 계약 위한 좁은 ABC.

Code

상속 + super()·python
class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        return f"{self.name} 가 소리냄"

class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name)            # Animal 이 자기 부분 init
        self.breed = breed

    def speak(self):                       # override
        return f"{self.name} ({self.breed}) 가 짖음"

d = Dog("Rex", "Lab")
print(d.name)              # 'Rex'  — Animal __init__ 에서 상속
print(d.breed)             # 'Lab'
print(d.speak())           # 'Rex (Lab) 가 짖음'
super().method() 호출 — 교체 X, 확장·python
class Logger:
    def log(self, msg):
        print(f"[LOG] {msg}")

class TimestampedLogger(Logger):
    def log(self, msg):
        import datetime
        stamped = f"{datetime.datetime.now().isoformat()}: {msg}"
        super().log(stamped)         # 변경된 msg 로 부모 버전 호출

tl = TimestampedLogger()
tl.log("hello")
# [LOG] 2026-05-02T12:34:56.789: hello
isinstance / issubclass·python
class Animal: pass
class Dog(Animal): pass
class Lab(Dog): pass

l = Lab()
print(isinstance(l, Lab))      # True
print(isinstance(l, Dog))      # True   — Lab 이 Dog 상속
print(isinstance(l, Animal))   # True   — Animal 도

print(issubclass(Lab, Animal)) # True
print(issubclass(Dog, Lab))    # False  — Dog 는 부모, 서브클래스 X

# isinstance 는 타입 tuple 받음
print(isinstance(l, (Lab, str)))   # True
상속보다 합성 — 같은 문제 두 가지로·python
# 상속 — Car IS an Engine. 잘못된 관계.
class Engine:
    def start(self):
        return "vroom"

class CarBad(Engine):                # 안 좋음 — Car 가 Engine 아님
    def drive(self):
        return self.start() + " go"

# 합성 — Car HAS an Engine. 맞는 관계.
class CarGood:
    def __init__(self):
        self.engine = Engine()       # 합성

    def drive(self):
        return self.engine.start() + " go"

c = CarGood()
print(c.drive())

# 엔진 교체 쉬움
class ElectricMotor:
    def start(self):
        return "hum"

c.engine = ElectricMotor()           # 구현 교체, 상속 변경 X
print(c.drive())                     # 'hum go'

External links

Exercise

Shape 정의 — __init__(name) + 메서드 describe()f"{self.name} shape" 반환. 서브클래스 Rectangle(width, height)Circle(radius). 각 서브클래스 — (a) 적절한 이름으로 super().__init__ 호출, (b) describe override 해서 차원 포함. 그 다음 클래스 Drawing — shape list 합성, add(shape) 메서드, show() 메서드 (각 shape 의 describe() 출력). 각 shape 최소 둘로 테스트.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.