클래스 상속은 물려받은 기능 유지한채로 다른 기능 추가할 때 사용한다.
상속 개념은 클래스마다 중복되는 부분을 반복해서 만들 필요 없이 재사용 할 수 있어서 효율적이다.
class 기반클래스이름:
코드
class 파생클래스이름(기반클래스이름):
코드
기반 클래스는 부모 클래스고 파생 클래스는 자식 클래스이다.
class Person:
def greeting(self):
print('안녕하세요.')
class Student(Person):
def study(self):
print('공부하기')
james = Student()
james.greeting() # 안녕하세요.: 기반 클래스 Person의 메서드 호출
james.study() # 공부하기: 파생 클래스 Student에 추가한 study 메서드
Student
클래스에 greeting
메서드가 없어도 사용할 수 있는 이유는 Person
클래스에서 상속 받았기 때문이다.
상속 관계를 is-a 관계라고 한다.
>>> Student is a Person
class Person:
def greeting(self):
print('안녕하세요.')
class PersonList:
def __init__(self):
self.person_list = [] # 리스트 속성에 Person 인스턴스를 넣어서 관리
def append_person(self, person): # 리스트 속성에 Person 인스턴스를 추가하는 함수
self.person_list.append(person)
다음과 같은 경우는 상속이 아닌 PersonList
가 Person
클래스를 포함하고 있는데 이를 포함 관계라 그런다.
포함 관계를 has-a 관계라고 한다.
>>> PersonList has a Person
파생 클래스의 메서드에서 기반 클래스의 메서드를 호출하려면 어떻게 할까?
super().메서드()
를 사용하면 된다.
class Person:
def __init__(self):
print('Person __init__')
self.hello = '안녕하세요.'
class Student(Person):
def __init__(self):
print('Student __init__')
super().__init__() # super()로 기반 클래스의 __init__ 메서드 호출
self.school = '파이썬 코딩 도장'
james = Student()
print(james.school)
print(james.hello)
>>> 실행 결과
Student __init__
Person __init__
파이썬 코딩 도장
안녕하세요.
오버라이딩(overriding)은 기반 클래스의 메서드를 무시하고 새로운 메서드를 만든다는 뜻이다.
class Person:
def greeting(self):
print('안녕하세요.')
class Student(Person):
def greeting(self):
super().greeting() # 기반 클래스의 메서드 호출하여 중복을 줄임
print('저는 파이썬 코딩 도장 학생입니다.')
james = Student()
james.greeting()
>>> 실행 결과
안녕하세요.
저는 파이썬 코딩 도장 학생입니다.
여러 기반 클래스로부터 상속 받을때 사용한다.
class 기반클래스이름1:
코드
class 기반클래스이름2:
코드
class 파생클래스이름(기반클래스이름1, 기반클래스이름2):
코드
class A:
def greeting(self):
print('안녕하세요. A입니다.')
class B(A):
def greeting(self):
print('안녕하세요. B입니다.')
class C(A):
def greeting(self):
print('안녕하세요. C입니다.')
class D(B, C):
pass
x = D()
x.greeting() # 안녕하세요. B입니다.
복잡한 클래스 상속으로 A가 부모 클래스이고 B, C는 A를 상속받는다. 그리고 D는 B, C를 상속받는다.
그런데 왜 기반 클래스가 출력이 안되고 B가 출력이 됐을까?
메서드 탐색 순서
파이썬은 메서드 탐색 순서(Method Resolution Order, MRO)를 따른다.
D.mro()
>>> 출력 값
[__main__.D, __main__.B, __main__.C, __main__.A, object]
D 클래스에 호출 순서를 보면 D -> B가 나온다.
그래서 바로 B의 greeting이 출력된다.
추상 클래스(abstract class)는 메서드의 목록만 가지며 상속받는 클래스에서 메서드 구현을 강제하기 위해 사용한다.
사용하는 방법
from abc import *
class 추상클래스이름(metaclass=ABCMeta):
@abstractmethod
def 메서드이름(self):
코드
from abc import *
class StudentBase(metaclass=ABCMeta):
@abstractmethod
def study(self):
pass
@abstractmethod
def go_to_school(self):
pass
class Student(StudentBase):
def study(self):
print('공부하기')
def go_to_school(self):
print('학교가기')
james = Student()
james.study()
james.go_to_school()
>>> 실행 결과
공부하기
학교가기
@abstractmethod
를 붙이는데 상속받은 클래스의 메서드는 @abstractmethod
가 붙은 메서드를 모두 구현해야 한다.
만약 Student
클래스에서 모두 구현하지 않았다면 에러가 나온다.
참고한 사이트
파이썬 코딩도장 Unit 36
(https://dojang.io/mod/page/view.php?id=2384)