본문 바로가기
Python/Python 기초

[Python] 상속과 다형성

by snow_white 2022. 3. 15.

상속이란?

부모 클래스의 모든 멤버를 자식에게 물려줄 수 있는 것

부모 클래스  →   자식 클래스
    일반화     →   특정기능추가
  • 새로운 메서드를 추가
  • 인스턴스에 새로운 속성 추가
  • 기존 메서드 일부를 재정의(redefine,overriding)

다형성이란?

상속받은 메소드의 바디를 덮어쓰기

 

class Employee:
    total_count = 0
    
    def __init__(self, name, birthdate, salary):
        self.name = name
        self.birthdate = birthdate
        self.salary = salary
        
        Employee.total_count += 1
        
    def show_info(self):
        print(f'이름: {self.name}, 생년월일: {self.birthdate.get_date()}, 급여: {self.salary}', end='')

Employee 클래스를 상속받고 싶을 땐 자식 클래스에서 Employee를 매개변수로 받아야 한다.

자식클래스 인스턴스 객체를 생성할 때 생성자에서 Employee 클래스에 있는 멤버변수를 그대로 사용하여 초기화해주어야 한다.

자식클래스 생성시 멤버변수 초기화할 때 super() 방식과 직접 클래스를 명시해주는 방식이 있다.

클래스를 직접 명시하여 부모 클래스의 생성자를 호출할 때는 첫 번째 매개변수 인자로 self를 꼭 넣어준다.

  • super().__init__(name, birthdate, salary)
  • Employee.__init__(self, name, birthdate, salary)

 

부모클래스인 Employee를 상속받은 Manager 자식클래스에서 show_info( ) 메소드가 재정의하여 호출하면,

자식 인스턴스 객체는 자식 클래스에 정의되어 있는 show_info( ) 메소드를 수행한다.

만약 부모클래스의 show_info( ) 메소드를 호출하고 싶다면 super.show_info( )와 같이 호출한다.

# 클래스 선언할 때 매개변수로 부모 클래스 넣어주면 상속됨
class Manager(Employee): 
    def __init__(self, name, birthdate, salary, dept):
        super().__init__(name, birthdate, salary)
        # Employee.__init__(self, name, birthdate, salary)
        self.dept = dept
        
    def show_info(self):
        super().show_info()
        print(f', 부서 {self.dept} 입니다')
        
m = Manager('김연아', Birthdate(1988,1,1), 300000, 'IT')
m.show_info() # 이름: 김연아, 생년월일: (1988, 1, 1), 급여: 300000, 부서 IT 입니다

 

 

mro (Method Resolution Order)

상속관계에서 메소드 우선 순위를 알아볼 때 사용
더 구체화 된 클래스가 우선순위 더 높음! 자식이 더 먼저!

 

print(Employee.mro())
print(Manager.mro())

'''
[<class '__main__.Employee'>, <class 'object'>]
[<class '__main__.Manager'>, <class '__main__.Employee'>, <class 'object'>]
'''

 

다중상속이란?

2개 이상의 클래스를 동시에 상속받는 것

단일 상속만 하더라도 재사용을 위해서는 hasing을 사용하자.

 

다중상속의 이름충돌(name conflict) 해결

자식클래스를 정의할 때 매개변수로 들어오는 순서대로 우선순위가 높은 부모클래스가 된다.

class Tiger:
    def jump(self):
        print('호랄이처럼 멀리 점프하기')
    def cry(self):
        print('호랑이 : 어흥')
class Lion:
    def bite(self):
        print('사자처럼 한입에 꿀꺽하기') 
    def cry(self):
        print('사자 : 으르렁')
class Liger(Tiger, Lion):
    def play(self):
        print('라이거만의 사육사와 재미있게 놀기')
        
l = Liger()
l.cry() # 호랑이 : 어흥
l.play() # 라이거만의 사육사와 재미있게 놀기
l.bite() # 사자처럼 한입에 꿀꺽하기

자식클래스를 생성할 때 매개변수 순서에 따라 Liger의 경우 Tiger가 우선순위가 높고, 그 다음이 Lion이다.

따라서 자식클래스인 Liger 인스턴스 객체를 생성하여 부모클래스의 함수를 호출하면 먼저 들어온 매개변수의 부모클래스에 해당하는 함수를 수행한다.

댓글