※ 이 글을 쓰는 사람은 SW 비전공자입니다.
※ 개인 공부를 위해 정리하는 글이며, 작성한 코드들은 효율성, 깔끔함(?) 등과는 거리가 멀 수 있습니다.
2021.03.14 - [코딩/Python] - [Python/파이썬] Class(클래스) 기초 정리 - 1 : 개념, 사용법
2021.03.20 - [코딩/Python] - [Python/파이썬] Class(클래스) 기초 정리 - 2 : has-a 관계, 상속 개념
2021.03.21 - [코딩/Python] - [Python/파이썬] Class(클래스) 기초 정리 - 3 : 다중상속, super().__init__(), 메서드 오버라이딩
2021.03.22 - [코딩/Python] - [Python/파이썬] Class(클래스) 기초 정리 - 4 : 추상 클래스, 클래스 변수
2021.03.27 - [코딩/Python] - [Python/파이썬] Class(클래스) 메서드 self 설명
1편에서는 Class의 개념이 무엇인지, 파이썬에서 기본 사용법은 어떻게 되는지 정리했다. 2편에서는 객체 속에 객체가 있는 has - a 관계와 클래스 상속 개념에대해서 정리했다. 이번 편에서는 다중 상속, super().__init__() 개념, 메서드 오버라이딩 개념에 대해 공부한 부분을 정리하려고 한다.
1. 다중상속(Multiple Inheritance)
다중상속은 말그대로 하위클래스가 부모클래스를 여러개 두는 것이다.(여러 클래스에서 상속받음) 이 개념은 객체 지향을 지원하는 언어 모두 사용가능한 것은 아니다. java의 경우에는 지원하지 않는다고 한다. 파이썬에서는 다중상속을 지원한다.
아래 코드를 예시로 작성해보았다.
#Weapone 클래스 정의
class Weaone:
def attack(self):
print("무기는 공격할 수 있어!")
#Thing 클래스 정의
class Thing:
def sell(self):
print("나는 물건이니 판매할 수도 있지")
#Sword 클래스 정의 : Weapone과 Thing 클래스 상속
class Sword(Weapone, Thing):
pass
#Sword 클래스 객체 short_sword 선언
short_sword = Sword()
#Weapone 클래스의 메소드 호출
short_sword.attack()
#Thing 클래스의 메소드 호출
short_sword.sell()
<결과>
무기는 공격할 수 있어!
나는 물건이니 판매할 수도 있지
Weapone(무기) 클래스와 Thing(물건) 클래스를 정의하였고 Sword(검) 클래스를 정의하여 앞에서 정의한 2가지 클래스를 상속받았다. Sword 클래스로 인스턴스를 생성하면 2개의 부모클래스에 있는 메소드를 호출할 수 있다.
2. super().__init__()에 대해서
: 부모 클래스의 초기화 메서드 호출하기 (자식 클래스 초기화 메서드에서 호출이 필요할 때)
이 내용은 상속에서 자식 클래스의 초기화 메서드에서 부모 클래스의 초기화 메서드를 호출할 때 필요한 내용이다. 참고로 자식 클래스에서 초기화 메서드를 사용하지 않으면 해당 방법을 사용하지 않아도 된다. 다음과 같은 예시코드를 작성하여 출력해보았다.
#Weapone 클래스 정의
class Weapone:
def __init__(self):
self.what = "무기"
self.type = "근거리"
print("나는 무기 클래스다!")
#Sword 클래스 정의 : Weapone 클래스 상속
class Sword(Weapone):
def __init__(self, power, level):
self.power = power
self.level = level
#Sword 속성(power,level) 및 부모 클래스 Weapon 의 속성 불러오기(what, type)
def info(self):
print("공격력 : ",self.power)
print("필요레벨 : ",self.level)
print("무기종류 : ", self.what)
print("공격타입 : ", self.type)
#Sword 클래스 객체 short_sword 선언
short_sword = Sword(10, 20)
short_sword.info()
<결과>
print("무기종류 : ", self.what)
AttributeError: 'Sword' object has no attribute 'what'
에러가 발생한다. 자식 클래스인 Sword에서 정의되지 않은 what과 type이 호출됐기 때문이다. what과 type은 부모클래스에 정의되어 있는데 호출하기 위해선 super().__init__()이라는 생성자를 호출해야 한다. 해당 구문은 자식 클래스 초기화 메서드에서 상속받은 부모클래스의 초기화 메서드를 그대로 불러오기 위해서 사용한다.
말이 조금 어려운데 쉽게 설명하면 자식 클래스 def __init__() 에서 부모 클래스의 def __init__()을 호출하려면 위 구문을 사용해야한다는 의미이다. 위 코드를 정상적으로 출력하게 하려면 Sword 클래스의 초기화 메서드 부분을 아래와 같이 수정하면 된다.
class Sword(Weapone):
def __init__(self, power, level):
super().__init__() #부모 클래스의 초기화 메서드 호출
self.power = power
self.level = level
<결과>
나는 무기 클래스다!
공격력 : 10
필요레벨 : 20
무기종류 : 무기
공격타입 : 근거리
super().__init__() 을 응용하여 아래와 같이 코드를 추가 작성해보았다. 효율적인 코드 구조인지는 잘 모르겠다. 여기서는 위 내용을 이해하기 위해서 테스트 코드를 작성해본 것이다. super().__init__(인수1, 인수2) 구조로 사용하여도 정상적으로 결과가 출력된다.
#Weapone 클래스 정의
class Weapone:
def __init__(self, what, type):
self.what = what
self.type = type
print("나는 무기 클래스다!")
#Sword 클래스 정의 : Weapone 클래스 상속
class Sword(Weapone):
def __init__(self, power, level, what, type):
super().__init__(what, type) #부모클래스의 초기화 생성자 호출, what, type 인수)
self.power = power
self.level = level
#Sword 속성(power,level) 및 부모 클래스 Weapon 의 속성 불러오기(what, type)
def info(self):
print("공격력 : ",self.power)
print("필요레벨 : ",self.level)
print("무기종류 : ", self.what)
print("공격타입 : ", self.type)
#Sword 클래스 객체 short_sword 선언
short_sword = Sword(10, 20, "단검", "근거리") #부모클래스 속성 포함 입력
short_sword.info()
<결과>
나는 무기 클래스다!
공격력 : 10
필요레벨 : 20
무기종류 : 단검
공격타입 : 근거리
위 코드가 복잡해서 아래처럼 도식화해보았다. 즉, 자식 클래스 초기화 메서드 내용에 부모 클래스의 초기화 메서드 내용을 그대로 가져다가 붙힌 것을 super().__init__() 한 줄 코드로 표현한 것이라고 이해하면 될 것 같다.
3. 메서드 오버라이딩
메서드 오버라이딩은 클래스 상속 관계에서 자식 클래스가 부모 클래스의 메서드를 덮어써서 다른 함수로 사용하는 것이다. 예를 들면 아래와 같은 코드다.
#Weapone 클래스 정의
class Weapone:
def attack(self):
print("무기는 공격할 수 있다")
#Sword 클래스 정의 : Weapone 클래스 상속
class Sword(Weapone):
def attack(self): #메서드 오버라이딩
print("칼을 무엇이든지 벨 수 있다")
super().attack() #부모 클래스의 attack 메서드 호출
short_sword = Sword()
short_sword.attack()
<결과>
칼을 무엇이든지 벨 수 있다
무기는 공격할 수 있다
부모 클래스의 attack 메서드가 있지만 자식 클래스에서 동일한 명칭의 attack 메서드를 재정의 하였다. 출력 결과를 보면 덮어씌어진 것으로 보인다. super().attack()의 경우 부모 클래스 원본 attack 메서드를 출력해보기 위해 임의로 입력해보았다.
참고링크1 : 코딩도장 - 다중상속 dojang.io/mod/page/view.php?id=2388
참고링크2 : 코딩도장 - 기반 클래스의 속성 사용하기 dojang.io/mod/page/view.php?id=2386
'코딩 > Python' 카테고리의 다른 글
[Python/파이썬] Class(클래스) 메서드 self 설명 (0) | 2021.03.27 |
---|---|
[Python/파이썬] Class(클래스) 기초 정리 - 4 : 추상 클래스, 클래스 변수 (0) | 2021.03.22 |
[Python/파이썬] Class(클래스) 기초 정리 - 2 : has-a 관계, 상속 개념 (0) | 2021.03.20 |
[Python/파이썬] Class(클래스) 기초 정리 - 1 : 개념, 사용법 (0) | 2021.03.14 |
[Python/파이썬] PyQT5 및 QT Designer 소개, .ui 파일 .py로 변환 방법 (0) | 2021.03.06 |