Python Inheritance, Abstract class, Overriding

김기현·2022년 1월 12일
post-thumbnail

Python의 inheritance(상속) 개념

파이썬 inheritance(상속)이란 부모 class(super class)의 속성(property)과 함수(method)를 그대로 물려받는 것을 뜻합니다.

1. 클래스 inheritance(상속)하기

super class의 속성, 함수를 sub class(자식 클래스)가 물려받을 때 super class의 속성과 함수를 사용할 수 있습니다.

class Dog:
    """Super Class"""
    #1 클래스 변수
    total_count = 0
    
    #2 생성자 메서드(method)
    def __init__(self, name, age):
        self.name = 'mungchi'
        self.age = age
        Dog.total_count+=1
    
    #3 class내 정의된 메서드(method)
    def introduce_dog(self):
        print(f'이름은 {self.name} 이고, 나이는 {self.age}살 입니다.')

#2 생성자 메서드에서 첫 번째 인자로 self를 입력합니다.(일반적으로 self를 많이 사용합니다.)

super class instance(인스턴스) 생성과 objects(객체)

d1 = Dog()
d2 = Dog()
d3 = Dog()

instance(인스턴스)는 정의된 class로 부터 생성된 것을,
object(객체)는 d1, d2, d3를 말합니다.

#1 클래스 변수의 출력

p1.__class__.total_count

# 3

#2 클래스 변수의 출력

d1 = Dog('mungchi', 10)
d1.introduce_dog()

# 이름은 mungchi 이고, 나이는 10살 입니다.

클래스 inheritance(상속) 받기

sub class의 함수를 정의하게 되면 정의된 함수로 실행합니다.

부모 클래스의 속성을 생성하고 초기화시켜주기 위해서는 Dog 클래스의 init 메서드를 호출해야 하는데, 이는 super()라는 함수를 이용합니다.

super().__init__() 호출시 name과 age argument를 넘겨줍니다.


class Little_Dog(Dog):
    """Sub Class"""

    def __init__(self, name, age):
        super().__init__(name, age)

   def introduce_dog(self):
        print(f'이름은 {self.name} 이고, 나이는 {self.age}살 입니다.')
puppy = Little_Dog('mungchi', 10)
puppy.introduce_dog()
# 이름은 mungchi 이고, 나이는 10살 입니다.

Little_Dog 클래스의 __init__().__init__(name, age) 인자를 받는 생성자 메서드로 정의합니다.


class Little_Dog(Dog):
    """Sub Class"""

    def __init__(self):
        super().__init__("mungchi", 10)

    def print_name(self):
        print(f'이름은 {self.name} 입니다.')
        
    def print_age(self):
        print(f'나이는 {self.age} 입니다.')
Little_Dog.introduce_dog()
# 이름은 mungchi 이고, 나이는 10살 입니다.

잘못된 상속 받기


class Little_Dog(Dog):
    """Sub Class"""

    def __init__(self):
        super().__init__()

    def print_name(self):
        print(f'이름은 {self.name} 입니다.')
        
    def print_age(self):
        print(f'나이는 {self.age} 입니다.')


생성자 init함수에서 name, age agrument가 필요합니다.


2. 추상 클래스(Abstract class)

추상 클래스란 구현되지 않은 추상 메서드를 하나 이상 가지고 있는 클래스를 말하며 반드시 sub class(자식 클래스)에서 재정의를 해야 합니다.

아래의 코드는 장고를 활용해 추상 클래스를 사용하는 기본 틀입니다.

from django import forms
from django.contrib.auth.forms import UserCreationForm

class LoginForm(forms.Form):

	email = forms.EmailField()

class SignUpForm(UserCreationForm):

    username = forms.EmailField(label="Email")

위 코드는 추상 클래스의 기본 틀로 장고로 부터 얻은 forms, UserCreationForm 모듈을 받고, 추상클래스 안에 모듈을 지정합니다.

아래의 예시는 자식 클래스에서 재정의를 하지 않은 코드입니다.

from abc import modulename

class Puppy(modulename): 
    # abstractmethod 
    def introduce_dog(self): 
        pass 

class Tiny_Dog(Puppy): 
    pass 

a = Tiny_Dog() 
# TypeError: Can't instantiate abstract class Person with abstract methods introduce_dog

재정의를 하지 않으면 자식 클래스에 내가 원하는 특정 메서드가 존재할 수 없고, 자식 클래스와 이름은 같지만 다른 기능을 구현하는 메서드를 만들 수 없습니다.

아래의 코드처럼 자식 클래스에서 재정의를 해야 합니다.

from abc import modulename

class Puppy(modulename): 
    # abstractmethod 
    def introduce_dog(self): 
        pass 

class Tiny_Dog(Puppy): 
    def introduce_dog(self):
    	print("저는 작은 퍼피입니다")

a = Tiny_Dog() 
a.introduce_dog()
# 저는 작은 퍼피입니다

3. Method Overriding(메서드 오버라이딩)

Method Overriding이란 부모 클래스에서 선언된 메서드와 동일한 이름을 자식 클래스에서 사용하는데, 몇몇 메서드를 덮어 씌워 재정의하는 기능을 말합니다.

결론적으로 부모로 부터 물려받은 다른 기능들은 사용하되 내가 원하는 메서드만 수정하여 사용하고 싶을 때 사용합니다.

메서드 오버라이딩 하기

class Dog:
    """Super Class"""
    
    # 생성자 메서드(method)
    def __init__(self, name='mungchi', age='10'):
        self.name = name
        self.age = age
        
    # Dog의 메서드
    def introduce_dog(self):
        print(f'난 Dog이야! 이름은 {self.name} 이고, 나이는 {self.age}살이야.')

#1 클래스 메서드 오버라이딩 받지 않는 경우


class Little_Dog(Dog):
    """Sub Class"""

    def __init__(self):
        super().__init__()

위 코드는 부모 클래스의 introduce_dog이 실행됩니다.


puppy = Little_Dog()
puppy.introduce_dog()
# 난 Dog이야! 이름은 mungchi 이고, 나이는 10살이야.

#2 클래스 메서드 오버라이딩 받는 경우


class Little_Dog(Dog):
    """Sub Class"""

    def __init__(self):
        super().__init__()

	#메서드 오버라이딩
    def introduce_dog(self):
        print(f'난 Dog이야! 이름은 {self.name} 이고, 나이는 주인보다 적어.')

위 코드는 자식 클래스의 introduce_dog이 실행됩니다.


puppy = Little_Dog()
puppy.introduce_dog()
# 난 Dog이야! 이름은 mungchi 이고, 나이는 주인보다 적어.

#3 클래스 메서드 오버라이딩을 받고 안에서 super()을 호출한 경우

이 경우에는 클래스 메서드 오버라이딩을 다 받고 원래의 기능을 유지하면서(자식 메서드 호출) 부모클래스의 메서드가 호출됩니다


class Little_Dog(Dog):
    """Sub Class"""

    def __init__(self):
        super().__init__()

	#메서드 오버라이딩
    def introduce_dog(self):
    	super().introduce_dog()
        print(f'난 Dog이야! 이름은 {self.name} 이고, 나이는 주인보다 적어.')

puppy = Little_Dog()
puppy.introduce_dog()
# 난 Dog이야! 이름은 mungchi 이고, 나이는 10살이야.
# 난 Dog이야! 이름은 mungchi 이고, 나이는 주인보다 적어.

상속 구조

#3의 상속 구조는 다음과 같습니다.

[__main__.Dog, __main__.Little_Dog, object]
profile
피자, 코드, 커피를 사랑하는 피코커

0개의 댓글