python

class - 클래스 상속

bono.html 2022. 10. 11. 10:27

 

일반적으로는 별도의 모듈에서 부모 클래스를 만들고 import해서 사용하지만 예시에서는 구조를 쉽게 파악하기 위해 한 모듈에 작성했다.

 

클래스를 상속 받아서 부모 클래스의 메소드를 활용할 수 있다

# 클래스의 상속 : 다형성을 구사 가능

class Animal:
    def __init__(self):
        print('Animal 생성자')
        
    def move(self):
        print('움직이는 생물')
        
class Dog(Animal):  # 상속
    def __init__(self):
        print('Dog 생성자')
    def my(self):
        print('난 댕댕이~')

dog1 = Dog()
dog1.move()
dog1.my()

Dog 생성자
움직이는 생물
난 댕댕이~

 

 

자식 클래스에 지정한 생성자가 없다면 부모 클래스의 생성자를 사용한다

class Horse(Animal):
    pass

horse1 = Horse()
horse1.move()

Animal 생성자
움직이는 생물

 

 

클래스를 변수에 담아 사용하는 형태

class Person:
    say = '난 사람~'
    age = '22'
    
    def __init__(self, age):
        print('Person 생성자')
        self.age = age
        
    def printInfo(self):
        print('나이:{}, 이야기:{}'.format(self.age,self.say))
        
    def hello(self):
        print('안녕')
        
print(Person.say, Person.age)
# Person.printInfo() error
p = Person('24')
p.printInfo()
p.hello()

난 사람~ 22
Person 생성자
나이:24, 이야기:난 사람~
안녕

 

 

클래스를 새로 생성해서 상속받고 변수에 담는 형태

위 예시의 Person class 참고

class Employee(Person):
    pass

emp = Employee('26')
emp.printInfo()

Person 생성자
나이:26, 이야기:난 사람~

 

 

조심해야 할 생성자 오류

예시에서 emp = Employee('26')를 입력할 경우 Employee class의 생성자와 매개변수 형식이 다름으로 오류가 실행된다. 위의 예시는 오류가 나지 않는 이유는 자식 클래스에서 생성자를 만들지 않아서 부모 클래스(Person)의 생성자를 참고하기 때문이다.

class Employee(Person):
    def __init__(self):
        print('Employee 생성자')
# emp = Employee('26') error
emp = Employee()
emp.printInfo()

Employee 생성자
나이:22, 이야기:난 사람~

 

 

super()

자식 클래스를 먼저 확인하고 없는 멤버는 부모 클래스의 멤버를 참고하는 것이 기본적인 형태이다.

다만 super()를 활용한다면 부모 클래스를 참고한다.

class Employee(Person):
    say = '일하는 동물'
    subject = '근로자'
    
    def __init__(self):
        print('Employee 생성자')
    def printInfo(self):
        print('Employee의 printInfo 메소드')
    def empPrintInfo(self):
        print(self.say, self.age, self.subject)
        print(self.say, super().say)
        
emp = Employee()
emp.printInfo()
emp.empPrintInfo()

Employee 생성자
Employee의 printInfo 메소드
일하는 동물 22 근로자
일하는 동물 난 사람~

 

 

private로 변수 만들기  __

부모 클래스에서 변수 앞에 __ 를 붙이면 그 변수가 private 처리된다. 즉 자식 클래스에서 super() 로 해당 변수를 참고할 수 없다는 뜻이다.

 

 

super().__init__()으로 부모 생성자에 접근하기

super()에서 self 를 가지고 간다고 생각하면 쉽다.

class Worker(Person):
    def __init__(self, age):
        print('Worker 생성자')
        super().__init__(age)  #부모 생성자 호출

    def wPrintInfo(self):
        self.printInfo()
wor = Worker('28')
print(wor.say, wor.age)
wor.wPrintInfo()

Worker 생성자
Person 생성자
난 사람~ 28
나이:28, 이야기:난 사람~

 

 

클래스를 2중 상속 받는 경우

부모 클래스를 Bound call (예시에서 super() )혹은 UnBound call (예시에서 클래스 이름)으로 상속할 수 있다.

class programmer(Worker):
    def __init__(self, age):
        print('Programmer 생성자')
        # super().__init__(age)  # Bound call
        Worker.__init__(self, age) # UnBound call
    
    def ProShow(self):
        self.printInfo()
     
pr = programmer('30')
print(pr.say, pr.age)
pr.ProShow()

 

 

__bases__

상속받는 클래스를 확인할 수 있다. 최상위 클래스는 object이다.

print(type(pr))
print(type(wor))
print(programmer.__bases__, Worker.__bases__, Person.__bases__)

<class '__main__.programmer'>
<class '__main__.Worker'>
(<class '__main__.Worker'>,) (<class '__main__.Person'>,) (<class 'object'>,)