파이썬_클래스 상속

hou·2022년 1월 3일
0
2022년 01월 03일

클래스 상속(class inheritance)

클래스 상속은 물려받은 기능 유지한채로 다른 기능 추가할 때 사용한다.
상속 개념은 클래스마다 중복되는 부분을 반복해서 만들 필요 없이 재사용 할 수 있어서 효율적이다.


상속 클래스 만드는 방법

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)

다음과 같은 경우는 상속이 아닌 PersonListPerson 클래스를 포함하고 있는데 이를 포함 관계라 그런다.

포함 관계를 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)

profile
할 수 있다

0개의 댓글