클래스 상속
상속이란?
- 물려받은 기능을 유지한채로 다른 기능을 추가하는 것
기반 클래스
- 기능을 물려주는 클래스
파생 클래스
- 상속 받아 새롭게 만들어지는 클래스
구조
class 기반클래스이름: 코드 class 파생클래스이름(기반클래스이름): 코드
ex)
class Person: def hi(self): print("안녕하세요") class Student(Person): def study(self): print("공부하기") sunrin = Student() sunrin.hi() sunrin.study() --출력-- 안녕하세요 공부하기
Person클래스를 상속받은 Student클래스의 인스턴스는 기반클래스와 파생클래스의 메서드를 모두 사용할 수 있다.
상속관계 확인하기
print(issubclass(Student, Person)) --출력-- True
Student가 Person의 파생클래스이므로 True가 출력된다
상속관계
class Person: def hi(self): print("안녕하세요") class Student(Person): def study(self): print("공부하기")
Student는 사람(Person)이므로 같은 종류
-> 상속은 명확하게 같은 종류이며 동등한 관계일때 사용한다.
포함관계
class Person: def hi(self): print("안녕하세요") class PersonList: def __init__(self): self.person_list = [] def append_person(self, person): self.person_list(person)
사람 목록 PersonList와 사람(Person)은 동등한 관계가 아니라 포함 관계
기반클래스 속성 사용
class Person: def __init__(self): print("Person __init__") self.hello = '안녕하세요' class Student(Person): def __init__(self): print("Student __init__") self.school = 'sunrint' sunrin = Student() print(sunrin.school) print(sunrin.hello)
오류 메시지가 출력된다.
Person의 __init__메서드가 호출되지 않았기 때문에 sunrin.hello가 실행되지 못한다.
super()를 이용해 기반클래스 초기화
class Person: def __init__(self): print("Person __init__") self.hello = '안녕하세요' class Student(Person): def __init__(self): print("Student __init__") super().__init__() self.school = 'sunrint' sunrin = Student() print(sunrin.school) print(sunrin.hello) --출력-- Student __init__ Person __init__ sunrint 안녕하세요
super()로 기반클래스의 __init__메서드를 호출하셔 속성을 만들어 줄 수 있다.
기반클래스를 초기화하지 않아도 되는 경우
class Person: def __init__(self): print("Person __init__") self.hello = '안녕하세요' class Student(Person): pass sunrin = Student() print(sunrin.hello) --출력-- Person __init__ 안녕하세요
파생클래스에서 __init__메서드를 패스하면 기반클래스의 __init__가 자동으로 호출된다.
메서드 오버라이딩
class Person: def hi(self): print("안녕하세요") class Student(Person): def hi(self): print("sunrin") sunrin = Student() sunrin.hi() --출력-- sunrin
기반클래스와 파생클래스의 메서드 이름이 같으면 기반클래스의 메서드를 무시하고 파생클래스의 메서드를 호출한다.
사용이유
중복되는 기능은 파생 클래스에서 다시 만들지 않고, 기반 클래스의 기능을 사용하고 원래 기능을 유지하면서 새로운 기능을 덧붙일때 사용된다
class Person: def hi(self): print("안녕하세요") class Student(Person): def hi(self): super().hi() #super()로 기반 메서드를 초기화한다 print("저는 sunrin입니다") sunrin = Student() sunrin.hi() --출력-- 안녕하세요 저는 sunrin입니다
다중상속
구조
class 기반클래스1: 코드 class 기반클래스2: 코드 class 파생클래스(기반클래스1, 기반클래스2): 코드
ex)
class Person: def hi(self): print("안녕하세요") class University: def manage(self): print("학점관리") class Student(Person, University): def study(self): print("공부하기") sunrin = Student() sunrin.hi() sunrin.manage() sunrin.study() --출력-- 안녕하세요 학점관리 공부하기
Student클래스가 Person, University 클래스를 상속받아 hi, manage 메서드를 사용한다.
메서드 탐색 순서 확인
상속 관계가 복잡하게 얽혀 있다면 메서드 탐색 순서(MRO)를 살펴보는 것이 편리하다
- 클래스.mro()
print(Student.mro()) --출력 [<class '__main__.Student'>, <class '__main__.Person'>, <class '__main__.University'>, <class 'object'>]
추상 클래스
추상클래스란?
- 메서드의 목록만 가진 클래스이며 상속받는 클래스에서 메서드 구현을 강제하기 위해 사용한다.
구조
from abc import * class 추상클래스이름(metaclass = ABCMeta): @abstractmethod def 메서드이름(self): 코드
- 추상클래스를 만드려면 abc모듈을 가져와야한다.
ex)
from abc import * #abc모듈 임포트 class StudentBase(metaclass = ABCMeta): @abstractmethod def study(self): pass @abstractmethod def gotoschool(self): pass class Student(StudentBase): def study(self): print("공부") sunrin = Student() sunrin.study() --출력-- TypeError: Can't instantiate abstract class Student with abstract methods gotoschool
-> 추상클래스를 상속받았다면 @abstractmethod가 붙은 추상메서드를 모두 구현해야한다
-> gotoschool추상 메서드를 구현하지 않아서 오류가 난다.
fix)
from abc import * #abc모듈 임포트 class StudentBase(metaclass = ABCMeta): @abstractmethod def study(self): pass @abstractmethod def gotoschool(self): pass class Student(StudentBase): def study(self): print("공부") def gotoschool(self): print("학교") sunrin = Student() sunrin.study() sunrin.gotoschool() --출력-- 공부 학교
gotoschool추상 메서드를 구현해주면 오류없이 제대로 출력된다.
추상 메서드를 pass로 빈메서드로 만드는 이유
추상클래스는 인스턴스룰 만들수 없기 때문에 추상 메서드를 호출할일이 없기 때문이다
##정확힌 모르겠다##
'Emotion > 파이썬' 카테고리의 다른 글
모듈과 패키지 (0) | 2020.09.07 |
---|---|
예외처리 (0) | 2020.09.04 |
클래스_1 (0) | 2020.09.01 |
함수_2 (0) | 2020.08.26 |
파이썬 함수_1 (0) | 2020.07.08 |