클래스에서 자주 쓰이는 용어, 기능들의 설명이다.
우선 사람을 표현하는 클래스를 먼저 구현해 보겠다.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def print_name(self):
print(f'제 이름은 {self.name}입니다.')
def print_age(self):
print(f'제 나이는 {self.age}세 입니다.')
p1 = Person('Sam', 29)
p1.print_name()
p1.print_age()
## 출력 ##
제 이름은 Sam입니다
제 나이는 29세 입니다.
그 다음 대학생을 표현하는 클래스를 구현해 보겠다.
class Student:
def __init__(self, name, age, uni):
self.name = name
self.age = age
self.uni = uni
def print_name(self):
print(f'제 이름은 {self.name}입니다.')
def print_age(self):
print(f'제 나이는 {self.age}세 입니다.')
def print_University(self):
print(f'제 대학교는 {self.uni}입니다.')
위와 같은 경우, Person 클래스에서 사용했던 name과 age 속성, 그리고 get_name과 get_age 메소드를 중복해서 작성하고 있는 상황이다. 이러한 상황에서 같은 작업이 반복하는 낭비를 초래한다.
이럴때 중복된 속성과 메소드를 쉽게 포함시킬 수 있게 해주는 기능이 클래스의 상속이다.
생성자에서 super().init()를 활용하여 다른 클래스의 속성 및 메소드를 자동으로 불러와 해당 클래스에서도 사용이 가능하도록 해줍니다.
위의 Student 클래스에서 Person 클래스의 속성 및 메소드를 상속시켜 보겠다.
class Student(Person):
def __init__(self, name, age, uni):
super().__init__(name, age)
self.uni = uni
def print_University(self):
print(f'제 대학교는 {self.uni}입니다.')
s1 = Student('Sam', 27, '하버드')
s1.print_name()
s1.print_age()
s1.print_University()
## 출력 ##
제 이름은 Sam입니다.
제 나이는 27세 입니다.
제 대학교는 하버드입니다.
하위 클래스에서 상위 클래스의 메서드를 재정의(override)한다는 뜻이다. 즉, 메소드 이름은 같지만 부모 클래스와는 다른 메소드로 사용할 수 있다. (또한, super()를 사용하여 부모클래스의 메소드를 호출 할 수 있다.)
class Student(Person):
def __init__(self, name, age, uni):
super().__init__(name, age)
self.uni = uni
# 부모 클래스에 있는 메소드지만 다르게 사용할 수 있다.
def print_name(self):
print(f'저는 대학생 {self.name}입니다.')
def print_University(self):
# super()를 사용해 부모 클래스 메소드를 불러오기
super().print_name()
print(f'제 학점은 {self.uni}입니다.')
s2 = Student('Sam', 27, '서울대')
s2.print_name()
s2.print_University()
## 출력
저는 대학생 Sam입니다. #자식 클래스의 print_name 메소드
제 이름은 Sam입니다. #부모 클래스의 print_name 메소드
제 대학교는 서울대입니다.
추상 클래스란 메서드의 목록만 가진 클래스이며 상속받는 클래스에서 메서드 구현을 강제하기 위해 사용한다.
추상 클래스를 만들려면 import로 abc 모듈을 불러와야 한다(abc는 abstract base class의 약자). 그리고 클래스의 ( )(괄호) 안에 metaclass=ABCMeta를 지정하고, 메서드를 만들 때 위에 @abstractmethod를 붙여서 추상 메서드로 지정한다. 상위 클래스에서 메소드 선언 -> 하위 클래스에서 메소드 구현
##### 상위 클래스
클래스 기본 구조#####
from abc import ABCMeta
from abc import abstractmethod
class abstract_AClass(metaclass=ABCMeta):
@abstractmethod
def absctractMethod(self):
pass
##### 하위 클래스
class AClass(abstract_AClass):
def absctractMethod(self):
print("This is AClass!")
#### 상위 클래스 계산기
class abstract_Calculator(metaclass=ABCMeta):
@abstractmethod
def add(self, n1, n2):
pass
@abstractmethod
def sub(self, n1, n2):
pass
@abstractmethod
def mul(self, n1, n2):
pass
@abstractmethod
def div(self, n1, n2):
pass
⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇ 하위 클래스 ⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇
#### 하위 클래스 계산기
class Calculator(abstract_Calculator):
def add(self, n1, n2):
return n1 + n2
def sub(self, n1, n2):
return n1 - n2
def mul(self, n1, n2):
return n1 * n2
def div(self, n1, n2):
return n1 / n2
부모(추상) 클래스에서 메서드를 선언부만을 작성하고, 실제 내용은 상속받는 클래스에서 구현하도록 하기 위해 일부러 비워두는 개념이라고 보면 된다. 추상 클래스를 상속받는 자식 클래스의 주제에 따라서 상속 받는 메서드의 내용이 달라질 수 있기 때문이다.
이는 프로그램을 표준화하기에 용이하고 추후 유지보수도 용이하다는 점 등 많은 장점들을 가지고 있다는 뜻이다.