ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Python 문법 기초 26 - class 상속(self 와 super)
    Python 2022. 10. 22. 17:08

     

    # 클래스의 상속 : 다형성을 구사 가능
    
    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()
    
    class Horse(Animal):
        pass
    
    horse1 = Horse()
    horse1.move()
    
    
    <console>
    Dog 생성자
    움직이는 생물
    난 댕댕이
    
    Animal 생성자
    움직이는 생물

    Dog ()안에 부모 클래스를 넣으면 상속된다.

    dog1을 호출하면 Animal 메소드를 호출할 수 있다.

    dog1을 호출하면 생성자가 호출되는데 생성자가 없으면 부모 클래스인 Animal 의 생성자가 호출된다.

    생성자가 있으면 Dog의 생성자를 호출한다.

    파이썬에서는 java처럼 오버로드가 존재하지 않는다. 그러므로 같은 메소드명은 사용할 수 없다.

    Animal은 다른 파일로 만들어 두고 import 하는 것이 정석이다.

     

    # 클래스의 상속
    class Person:
        say = '난 사람~'
        nai = '22'
        
        def __init__(self, nai):
            print('Person 생성자')
            self.nai = nai # Person 객체의 nai 와 기억장소가 다르다.
            
        def printInfo(self):
            print('나이:{}, 이야기:{}'.format(self.nai, self.say))
            
        def hello(self):
            print('안녕')
            
    print(Person.say, Person.nai)
    # Person.printInfo() err () 안에 아무것도 넣어주지 않았기때문에
    p = Person('24') # 객체를 생성할 때 nai가 주어지며 다른 주소를 가지고 있다.
    p.printInfo()
    p.hello()
    
    
    <console>
    난 사람~ 22
    Person 생성자
    나이:24, 이야기:난 사람~
    안녕

    객체를 생성할 때 nai가 주어지며 기존 nai 와는 다른 주소를 가지고 있다.

     

     

    자식 클래스에 생성자가 없는 경우

    print('***' * 10)
    class Employee(Person):
        pass
    
    emp = Employee('25') // 부모클래스 생성자 호출
    emp.printInfo()
    
    
    <console>
    Person 생성자
    나이:25, 이야기:난 사람~

    Employee 를 호출했지만 생성자가 없다. 그러므로 부모 클래스인 Person의 생성자를 호출한다. Person의 생성자에는 필수 매개변수 값으로 nai가 들어가는데 부모클래스를 호출한 것이므로 nai의 값을 넣어주면 된다.

     

     

    자식 클래스에 생성자가 있는 경우

    class Employee(Person):
        def __init__(self):
            print('Employee 생성자')
            
    # emp = Employee('26')
    emp = Employee()
    emp.printInfo()
    
    <console>
    err
    Employee 생성자
    나이:22, 이야기:난 사람~

    Employee의 생성자가 존재하므로 Employee의 생성자가 실행되는데 매개변수 값으로 26을 부여했기 때문에 err가 발생했다. 그 이유는 Employee의 생성자에는 매개변수가 없기 때문이다.

    매개변수 값을 부여하지 않으면 부모 클래스를 호출하는데 self.nai는 비어있는 값이기 때문에 Person의 nai를 호출하게 된다.

     

    class Employee(Person):
    		say = '일하는 동물'
        subject = '근로자'
    
        def __init__(self):
            print('Employee 생성자')
            
        def printInfo(self):
            print('Employee의 printInfo 메소드')
    
    		def empPrintInfo(self):
            print(self.say, self.nai, self.subject)
    				print(self.say, super().say) # 부모 클래스의 say
    				self.printInfo()
            super().printInfo() # 부모 클래스의 printInfo
            
    emp = Employee()
    emp.printInfo()
    emp.empPrintInfo()
    
    
    <console>
    Employee 생성자
    Employee의 printInfo 메소드
    일하는 동물 22 근로자
    일하는 동물 난 사람~
    Employee의 printInfo 메소드
    나이:22, 이야기:일하는 동물

    부모 클래스와 자식 클래스의 메소드가 동일하면 호출한 클래스의 변수를 우선시 한다.

    empPrintInfo를 호출하면 self.say, self.nai의 값은 부모클래스에서 가져오게 된다.

    만약 empPrintInfo에 변수가 존재하면 그 변수 값을 가져오게 된다.

    super(). 을 사용하면 현재 클래스는 pass 하고 부모클래스의 say를 찾게 된다.

     

    class Person:
        say = '난 사람~'
        nai = '22'
        __kbs = '공영방송' # private 멤버 변수
        
        def __init__(self, nai):
            print('Person 생성자')
            self.nai = nai # Person 객체의 nai 와 기억장소가 다르다.
            
        def printInfo(self):
            print('나이:{}, 이야기:{}'.format(self.nai, self.say))
            
        def hello(self):
            print('안녕')

    __를 사용하면 private 멤버 변수로서 해당 클래스에서만 사용 가능하다. 상속은 불가능하다.

     

    class Worker(Person):
        def __init__(self, nai):
            print('Worker 생성자')
            super().__init__(nai) # 부모 생성자 호출
            # super()가 nai를 가지고 부모 생성자에게 간다.
    
        def wPrintInfo(self):
            self.printInfo()
            
    wor = Worker('28')
    print(wor.say, wor.nai)
    wor.wPrintInfo()
    
    
    <console>
    Worker 생성자
    Person 생성자
    난 사람~ 28
    나이:28, 이야기:난 사람~

     

    class Programmer(Worker):
        def __init__(self, nai):
            print('Programmer 생성자')
            # super().__init__(nai) # Bound call
            Worker.__init__(self, nai) # UnBound call
            
        def ProShow(self):
            self.printInfo()
    
    pr = Programmer('29')
    print(pr.say, pr.nai)
    pr.ProShow()
    
    
    <console>
    Programmer 생성자
    Worker 생성자
    Person 생성자
    난 사람~ 29
    나이:29, 이야기:난 사람~

    Programmer에서 직접 Person으로 갈 수는 없다. 부모인 Worker를 거처야 된다.

     

    print(type(3))
    print(type(pr))
    print(type(wor))
    print(Programmer.__bases__, Worker.__bases__, Person.__bases__)
    
    
    <console>
    <class 'int'>
    <class '__main__.Programmer'>
    <class '__main__.Worker'>
    (<class '__main__.Worker'>,) (<class '__main__.Person'>,) (<class 'object'>,)

    __bases__는 조상 클래스를 명시하는 함수이다.

    모든 class의 조상은 object class이다.

     

    댓글

Designed by Tistory.