class Parent:
pass
class Child(Parent):
pass
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self, food):
print(f'{self.name} {food} 먹습니다')
def sleep(self, hour):
print(f'{self.name} {hour}시간 동안 잠을 잡니다')
animal = Animal('동물', 10)
animal.eat('먹이')
animal.sleep(10)
동물 먹이 먹습니다
동물 10시간 동안 잠을 잡니다
class Dog(Animal):
pass
# Animal 클래스를 상속 받았기 때문에 Animal 클래스의 생성자
# 매개변수를 전달해야 함
Rucy = Dog('루시', 14)
Rucy.eat('사료')
Rucy.sleep(12)
루시 사료 먹습니다
루시 12시간 동안 잠을 잡니다
class Parent:
def __init__(self):
print('부모 클래스 생성자 호출')
class Child(Parent):
def __init__(self):
print('Child 클래스 생성자 호출')
super().__init__()
print('모든 생성자 호출 완료')
child = Child()
Child 클래스 생성자 호출
부모 클래스 생성자 호출
모든 생성자 호출 완료
파이썬에서 모든 클래스의 부모 클래스 역할을 하는 기본 클래스.
파이썬에서 정의하는 모든 클래스는 자동으로 Object 클래스를 상속받는다.
파이썬의 모든 객체는 Object 클래스에서 제공하는 기본적인 동작과 메서드를 사용할 수 있게 된다.
ex) __str__(), __repr__(), __eq__(), __hash__() 등.
class MyClass:
pass
# 위의 코드는 다음과 동일합니다.
class MyClass(object):
pass
서브 클래스(자식 클래스)에서 슈퍼 클래스(부모 클래스)의 메서드를 재정의하는 것을 의미.
오버라이딩을 사용하면, 서브 클래스에서 상속받은 메서드의 동작을 변경하거나 확장할 수 있다.
오버라이딩할 때, 메서드의 이름은 물론이고 매개변수의 타입과 개수도 일치해야 한다.
반환 타입은 일치할 필요는 없지만, 일반적으로 같게 유지하는 것이 좋다.
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self, food):
print(f'{self.name} {food} 먹습니다')
def sleep(self, hour):
print(f'{self.name} {hour}시간 동안 잠을 잡니다')
class Dog(Animal):
def run(self):
print(f'{self.name} 달립니다')
def eat(self, food):
print(f'{self.name} {food}를 아주 맛있게 먹습니다')
def superEat(self, food):
super().eat(food)
Rucy = Dog('루시', 14)
Rucy.eat('사료')
Rucy.sleep(12)
Rucy.run()
Rucy.superEat('사료')
animal = Animal('동물', 10)
animal.eat('먹이')
animal.sleep(10)
# animal.run() # error. 부모는 자식 클래스의 메소드 사용 X
루시 사료를 아주 맛있게 먹습니다
루시 12시간 동안 잠을 잡니다
루시 달립니다
루시 사료 먹습니다
동물 먹이 먹습니다
동물 10시간 동안 잠을 잡니다
class Parent1:
pass
class Parent2:
pass
class Child(Parent1, Parent2):
pass
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self, food):
print(f'{self.name} {food} 먹습니다')
def sleep(self, hour):
print(f'{self.name} {hour}시간 동안 잠을 잡니다')
class Human:
def __init__(self, name, age):
self.name = name
self.age = age
def study(self, hour):
print(f'{self.name} {hour}시간 동안 공부를 합니다')
def sleep(self, hour):
print(f'{self.name} {hour}시간 동안 꿀잠 잡니다')
class Kim(Animal, Human):
pass
kim = Kim('김사과', 20)
kim.eat('밥')
kim.study(2)
kim.sleep(8)
print(Kim.mro())
김사과 밥 먹습니다
김사과 2시간 동안 공부를 합니다
김사과 8시간 동안 잠을 잡니다
[<class '__main__.Kim'>, <class '__main__.Animal'>, <class '__main__.Human'>, <class 'object'>]
✔
class Kim(Animal, Human):
pass
이렇게 쓴 경우, Kim(Animal, Human) 이렇게 Animal이 먼저이므로,
Animal class를 먼저 찾고, Human class를 찾는다.
반대로 Kim(Human, Animal) 이렇게 되어 있다면, Human이 먼저이므로,
Human class를 먼저 찾고, Animal class를 찾는다.
class Base:
def hello(self):
print('Base의 hello()')
print('Base 클래스의 hello() 메서드')
class A(Base):
def hello(self):
print('A의 hello()')
super().hello()
print('A 클래스의 hello() 메서드')
class B(Base):
def hello(self):
print('B의 hello()')
super().hello()
print('B 클래스의 hello() 메서드')
class Child(A, B):
def hello(self):
print('Child의 hello()')
super().hello()
print('Child 클래스의 hello() 메서드')
child = Child()
child.hello()
Child.mro()
Child의 hello()
A의 hello()
B의 hello()
Base의 hello()
Base 클래스의 hello() 메서드
B 클래스의 hello() 메서드
A 클래스의 hello() 메서드
Child 클래스의 hello() 메서드
[__main__.Child, __main__.A, __main__.B, __main__.Base, object]
class Child(A, B) 이렇게 되어 있으므로,
부모 클래스 중 A 클래스 먼저 찾고, B 클래스를 찾는다.
Base 클래스가 제일 부모인 클래스이고, A와 B 클래스는 동등한 부모 클래스이다. (마치 엄마 아빠처럼!)
Base
↑
┌──┴──┐
A B
↑ ↑
└──┬──┘
Child
super()는 MRO 순서에 따라 다음 클래스의 메서드를 호출한다.
[<class '__main__.Child'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.Base'>, <class 'object'>]
즉, Child → A → B → Base → object 순서로 메서드를 탐색한다.
class Parent:
def hello(self):
print('부모 클래스의 hello 메서드')
class Child(Parent):
def hello(self):
super().hello()
print('자식 클래스의 hello 메서드')
child = Child()
child.hello()
부모 클래스의 hello 메서드
자식 클래스의 hello 메서드
class Parent:
def __init__(self, value):
self.value = value
class Child(Parent):
def __init__(self, value, child_value):
super().__init__(value)
self.child_value = child_value
child = Child(10, 20)
print(child.value)
print(child.child_value)
10
20