상속. 왠지 가슴뛰는 단어다.
공짜로 무엇인가를 물려받는것. (물론 많은 상속세를 내야하지만..)
클래스에는 상속세가 없다. ^^
클래스에서 상속이란 기존의 클래스를 가져와서 내가 고치고 싶은대로 추가하고 고쳐서 새로운 클래스를 만들수 있게 도와주는 기능이다.
- 기존의 클래스: base class, parent class, superclass
- 새로운 클래스: derived class, child class, subclass
어떻게 만들까?
class Cat:
def greeting(self):
print('야옹')
class StreetCat(Cat):
def introduction(self):
print('난 길고양이')
momo = StreetCat()
momo.greeting()
momo.introduction()
결과: 야옹 난 길고양이
- 새로운 클래스 = StreetCat
- 기존 클래스 = Cat
- 새로운 클래스 StreetCat() 안에 Cat 이라는 기존의 클래스를 넣어줌으로써, StreetCat 은 greeting method를 공짜로 물려받는다. 따라서, momo 로 인스턴스화를 시켰을때 momo뒤에는 기존 클래스 Cat안에 있는 greeting method에 접근할 수 있다.
만약에 두 클래스의 관계를 파악하고 싶을땐 이렇게 한다.issubclass(StreetCat, Cat)
StreetCat이 Cat의 subclass니? 정답은 True!
class Cat:
def __init__(self):
self.hello = '야옹'
class StreetCat(Cat):
def __init__(self):
self.hometown = '길'
momo = StreetCat()
print(momo.hometown)
print(momo.hello) #에러가 난다.
결과: 길
AttributeError: 'StreetCat' object has no attribute 'hello'
momo.hello는 에러간 났다. StreetCat은 hello라는 속성이 없다.
우리가 배운점. StreetCat(자식 클래스)는 부모클래스 Cat의 속성에는 접근할 수 없다.
방법이 없을까?
물론 있다! super()를 써주면된다.
class StreetCat(Cat):
def __init__(self):
super().__init__()
self.hometown = '길'
super( ).__init__( ) : 부모클래스로 가서 속성가져올께. 이렇게 코드를 고쳐주면 에러가 없어진다.
그럼 의문이 든다. 만약에 새로운 클래스 안에 속성을 지정해 주지 않으면? 예를 들어 StreetCat(Cat)안에 __init__이 없으면 파이썬은 부모 클래스 Cat의 속성을 대신 쓸까?
정답은 Yes!
Override는 영어에서 많이 쓰는 표현이다. 무시하다. 최우선시하다. 예를 들어 My mom usually overrides my dad when planning vacations. (여행 계획짤 때 엄마가 주로 승자다!)
만약에 부모클래스와 자식클래스에 똑같은 이름의 method가 있다고 한다면 누가 누구를 override 할까?
class Cat:
def greeting(self):
print('야옹')
class StreetCat(Cat):
def greeting(self):
print('야옹! 난 길고양이')
momo = StreetCat()
momo.greeting()
결과: 야옹! 난 길고양이
그렇다. 승자는 자식클래스다. 자식 이기는 부모 보았는가? 농담이고, 어쨋든 momo는 StreetCat, 새로운 클래스이고 새로운 클래스 안에 있는 method를 따르게 된다.
그럼, greeting을 두개 다 호출하려면 어떻게 해야 할까? super( )를 쓰자.
class StreetCat(Cat):
def greeting(self):
super().greeting()
print('야옹! 난 길고양이')
이렇게 써주면 야옹 야옹! 난 길고양이!
그럼 한개 이상의 class를 상속받는게 가능한가?
Yes!
새로운 클래스를 지정할때 괄호 안에 기존 클래스 이름을 , 로 구분해서 써주면 된다.
NewClass(OldClass1, OldClass2)
추상 클래스는 method의 목록만 갖고 있는 클래스이다. Method는 상속받는 클래스에서 정의 된다.
추상 클래스를 만들기 위해서 abc 모듈을 갖고와야 한다. abc는 abstract base class의 약자다.
from abc import *
class 추상클래스이름(metaclass=ABCMeta):
@abstractmethod
def 메서드이름(self):
pass
import * : abc에 있는 모듈을 다 가져와.
추상클래스이름에 metaclass=ABCMeta 써주기.
method위에 @abstractmethod 써주기.
pass: 코드는 자식 클래스에서 구현해줄께.
from abc import *
class Family(metaclass=ABCMeta):
@abstractmethod
def job(self):
pass
class Dad(Family):
def job(self):
print('사업가')
kim = Dad()
kim.job()
결과: 사업가
자식클래스인 Dad 에서 job method가 완성됐다.
주의할 것은 Family라는 클래스에 추상매서드가 한 개 이상이면 (예, job, age, weight) Dad 라는 서브클래스에서 모두 정의해 줘야 한다. 아니면 에러가 난다.
추상클래스에 대해 다음것만 기억하자!
추상 클래스는 상속에만 사용한다.
추상 클래스는 인스턴스로 만들지 않는다.
추상 클래스의 method는 물려받는 자식 클래스에서 모두 완성되야 한다.