⚙️
중급 (Intermediate)
extends · super · __str__ · __eq__ · classmethod
8주차 — 객체지향 (2) — 상속·다형성·매직 메서드
부모 클래스의 속성·메서드를 물려받는 상속, super() 호출, 다형성, __str__/__eq__/__add__ 같은 매직 메서드 오버라이딩, classmethod와 staticmethod까지.
inheritancesupermagicclassmethod
소요 시간
⏱ 2시간
난이도
📊 중급
선수 조건
🎯 7주차 (OOP 1)
결과물
Shape→Rectangle/Circle, Vector + 매직 메서드
이 강의에서 배우는 것
- 1클래스 상속과 super() 를 사용한다
- 2다형성을 코드로 보인다
- 3매직 메서드를 오버라이딩한다
- 4클래스 메서드와 정적 메서드를 구분한다
1. 상속
python
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "..."
class Dog(Animal): # Animal 상속
def speak(self): # 메서드 오버라이딩
return "멍멍"
d = Dog("바둑이")
print(d.name, d.speak()) # 바둑이 멍멍2. super()
python
class Puppy(Dog):
def __init__(self, name, age):
super().__init__(name) # 부모 __init__ 호출
self.age = age3. 다형성
같은 메서드 이름을 다양한 클래스에서 다르게 구현. 호출자는 타입을 신경 쓰지 않음.
python
animals = [Dog("바둑이"), Cat("나비"), Cow("얼룩이")]
for a in animals:
print(a.speak()) # 멍멍 / 야옹 / 음매4. 매직 메서드
이름이 __xxx__ 로 시작·끝나는 특별 메서드. 파이썬 문법과 연결됨.
| 메서드 | 트리거 |
|---|---|
| __str__ | str(x), print(x) |
| __repr__ | REPL에서 표시, repr(x) |
| __len__ | len(x) |
| __eq__ | x == y |
| __add__ | x + y |
| __getitem__ | x[i] |
| __iter__/__next__ | for ... in x |
python
class Point:
def __init__(self, x, y):
self.x, self.y = x, y
def __repr__(self):
return f"Point({self.x}, {self.y})"
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)
def __eq__(self, other):
return (self.x, self.y) == (other.x, other.y)
p = Point(1, 2) + Point(3, 4)
print(p) # Point(4, 6)
print(p == Point(4, 6)) # True5. classmethod / staticmethod
python
class Date:
def __init__(self, y, m, d):
self.y, self.m, self.d = y, m, d
@classmethod
def from_string(cls, s):
y, m, d = map(int, s.split("-"))
return cls(y, m, d) # 인스턴스 생성
@staticmethod
def is_valid(y, m, d):
return 1 <= m <= 12 and 1 <= d <= 31
print(Date.from_string("2026-05-09").y)
print(Date.is_valid(2026, 5, 9))6. 자주 하는 실수
- super().__init__() 누락 — 부모 속성이 초기화 안 됨
- 매직 메서드를 일반 호출 — p.add(q) 가 아니라 p + q
- __eq__ 만 만들고 __hash__ 빼먹음 — set/dict 키로 못 씀
- 다중 상속 남용 — 가능하지만 복잡. 가능하면 컴포지션
7. FAQ
Q1. 추상 클래스(인터페이스) 만들려면?
abc.ABC 와 @abstractmethod 사용.
Q2. __str__ vs __repr__ ?
__str__ 은 사람용, __repr__ 은 개발자용 (디버깅). 보통 __repr__ 만 정의해도 됨.
Q3. 상속 vs 컴포지션?
"is-a" 관계면 상속, "has-a" 면 속성 보유 (컴포지션). 의심되면 컴포지션.
💻 예제 (examples)
실제로 실행해 결과를 확인할 수 있는 예제 코드입니다.
01_inherit.py— 상속 + super
CODE
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "..."
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name)
self.breed = breed
def speak(self):
return "멍멍"
d = Dog("바둑이", "진돗개")
print(d.name, d.breed, d.speak())
▶ 실행 결과
바둑이 진돗개 멍멍02_polymorphism.py— 다형성
CODE
class Animal:
def speak(self): return "..."
class Dog(Animal):
def speak(self): return "멍멍"
class Cat(Animal):
def speak(self): return "야옹"
class Cow(Animal):
def speak(self): return "음매"
for a in [Dog(), Cat(), Cow()]:
print(a.speak())
▶ 실행 결과
멍멍
야옹
음매03_magic.py— 매직 메서드 (Point)
CODE
class Point:
def __init__(self, x, y):
self.x, self.y = x, y
def __repr__(self):
return f"Point({self.x}, {self.y})"
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)
def __eq__(self, other):
return (self.x, self.y) == (other.x, other.y)
p = Point(1, 2) + Point(3, 4)
print(p)
print(p == Point(4, 6))
print([Point(0,0), p]) # __repr__ 활용
▶ 실행 결과
Point(4, 6)
True
[Point(0, 0), Point(4, 6)]04_classmethod.py— classmethod / staticmethod
CODE
class Date:
def __init__(self, y, m, d):
self.y, self.m, self.d = y, m, d
@classmethod
def from_string(cls, s):
y, m, d = map(int, s.split("-"))
return cls(y, m, d)
@staticmethod
def is_valid(y, m, d):
return 1 <= m <= 12 and 1 <= d <= 31
dt = Date.from_string("2026-05-09")
print(dt.y, dt.m, dt.d)
print(Date.is_valid(2026, 13, 1))
▶ 실행 결과
2026 5 9
False📝 과제 (exercises)
직접 풀어보고, 막힐 때 정답을 펼쳐 비교해보세요.
과제 1
Shape 추상 → Rectangle, Circle
목표: Shape 클래스를 상속해 Rectangle, Circle 구현.
요구사항
- Shape — area() 메서드 (기본 구현은 0 또는 abstract)
- Rectangle, Circle — area 오버라이딩
- 도형 리스트를 순회해 면적 출력
입출력 예시
Rectangle: 200
Circle: 78.54▶정답 코드 펼치기 / 접기
SOLUTION
import math
class Shape:
def area(self):
return 0
class Rectangle(Shape):
def __init__(self, w, h):
self.w, self.h = w, h
def area(self):
return self.w * self.h
class Circle(Shape):
def __init__(self, r):
self.r = r
def area(self):
return math.pi * self.r ** 2
shapes = [Rectangle(10, 20), Circle(5)]
for s in shapes:
print(f"{type(s).__name__}: {s.area():.2f}")
▶ 실행 결과
Rectangle: 200.00
Circle: 78.54과제 2
Playlist 클래스 + 매직 메서드
목표: 노래 리스트로 __len__, __getitem__, __add__ 구현.
요구사항
- songs 속성에 곡 리스트
- len(p), p[0], p1 + p2 동작
입출력 예시
len: 3
첫 곡: 봄날
합치기 후 len: 5▶정답 코드 펼치기 / 접기
SOLUTION
class Playlist:
def __init__(self, songs=None):
self.songs = list(songs) if songs else []
def __len__(self):
return len(self.songs)
def __getitem__(self, i):
return self.songs[i]
def __add__(self, other):
return Playlist(self.songs + other.songs)
p1 = Playlist(["봄날", "Spring Day", "FAKE LOVE"])
p2 = Playlist(["DNA", "Butter"])
print(f"len: {len(p1)}")
print(f"첫 곡: {p1[0]}")
print(f"합치기 후 len: {len(p1 + p2)}")
▶ 실행 결과
len: 3
첫 곡: 봄날
합치기 후 len: 5과제 3
Vector 클래스 (+, -, ==, repr)
목표: 2D 벡터 합·차·비교·표현.
요구사항
- x, y 속성
- __add__, __sub__, __eq__, __repr__
입출력 예시
Vector(4, 6)
Vector(-2, -2)
True▶정답 코드 펼치기 / 접기
SOLUTION
class Vector:
def __init__(self, x, y):
self.x, self.y = x, y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __sub__(self, other):
return Vector(self.x - other.x, self.y - other.y)
def __eq__(self, other):
return (self.x, self.y) == (other.x, other.y)
def __repr__(self):
return f"Vector({self.x}, {self.y})"
a = Vector(1, 2)
b = Vector(3, 4)
print(a + b)
print(a - b)
print(a + b == Vector(4, 6))
▶ 실행 결과
Vector(4, 6)
Vector(-2, -2)
True