※ 이 글을 쓰는 사람은 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. 인스턴스 변수
1) 인스턴스 vs 객체
C++이든 파이썬이든 객체 지향 프로그래밍을 지원하는 언어라면 인스턴스와 객체라는 단어를 많이 쓴다. 어떤 코드를 설명하는 글을 읽을 때 이 2개를 혼용해서 쓰는 경우가 많아 굉장히 헷갈린다. (사실 아직 이해가 정확히 안감..)
이전 포스팅에서 클래스를 무기로 클래스에 비유해서 설명해봤는데 이번에도 같은 코드로 설명해보겠다. 객체와 인스턴스의 차이는 위키 독스-'점프 투 파이썬'에서 잘 설명하여 참고하여 정리했다.
# 무기 클래스 정의
class Weapone():
pass
#'무기' 클래스 객체 '칼'을 생성해보기"
sword = Weapone()
-. sword는 객체이다.
-. sword 객체는 Weapone 클래스의 인스턴스이 다.
: 인스턴스는 어떤 클래스의 객체인지 관계를 설명할 때 사용하는 용어라고 한다.
-. 객체랑 인스턴스 모두 비슷한 경우에 사용하여 헷갈리므로 위와 같이 정리
2) 인스턴스 변수
각 인스턴스들은 같은 클래스로 선언하여도 다른 변수를 가질 수 있다. 아래와 같은 코드를 생각해보자. 결과를 보면 알겠지만 같은 클래스여도 다른 변수를 가질 수 있다. 동일한 변수여도 다른 값을 가질 수 있다.
#무기 클래스를 선언. 내부 내용은 아무 것도 없음(pass)
class Weapone:
pass
#sword 객체 선언
sword = Weapone()
sword.power = 10
sword.level = 5
#gun 객체 선언
gun = Weapone()
gun.power = 20
gun.type = "원거리"
#같은 class이지만 각각 다른 변수를 가질 수 있다.
print("칼의 공격력 : ",sword.power)
print("칼의 레벨제한 : ",sword.level)
print("총의 공격력 : ",gun.power)
print("총의 공격타입 : ",gun.type)
<결과>
칼의 공격력 : 10
칼의 레벨제한 : 5
총의 공격력 : 20
총의 공격타입 : 원거리
Process finished with exit code 0
2. has - a 관계 (객체 속의 객체)
has - a 관계는 객체가 다른 객체를 포함한다는 말이다. 쉽게 설명하기 위해 이전에 설명했던 게임을 비유로 해보겠다.
RPG 게임에는 소지품을 보관할 수 있는 인벤토리(혹은 가방, 창고) 개념이 있다. 이 인벤토리도 생각해보면 또 다른 클래스 개념으로 생각할 수 있다. 인벤토리는 보관 최대 개수, 공간 등의 속성을 가진다.
무기 클래스의 칼과 총(객체)는 이 게임 유저의 인벤토리(객체)에 들어갈 수 있다. 이런 관계를 has - a 관계라고 한다.
어려우니까 다시 도식화를 쉽게 해보았다.
위 도식화에 맞게 코드를 짜보았다. 인벤토리에 대한 클래스를 선언하고 __int__에서 기본 인벤토리에 대한 속성 값을 정의하였다. 그리고 인벤토리를 열고 닫는 메서드, 아이템을 넣는 메서드를 정의하였다.
(아래 코드는 위키 독스 - '왕초보를 위한 python'을 참고함. 참고 링크는 본문 하단에 기재.)
class Inventory:
#인벤토리 기본속성 : 닫혀있다. 빈공간이다.(리스트로 선언)
def __init__(self):
self.opend = False
self.item_space = []
#인벤토리 열기 메소드 : 열려있는 상태로 변경한다.
def open(self):
self.opened = True
print("인벤토리가 열렸습니다. 아이템을 넣을 수 있습니다.")
#인벤토리에 아이템 넣기 메소드 : 기본 속성인 item_space에 아이템을 추가한다.
def put(self, something):
if self.opened == True:
self.item_space.append(something)
print('아이템을 인벤토리에 넣었습니다.')
else:
print("인벤토리를 먼저 열어주세요")
#인벤토리 닫기 메소드 : 닫혀있는 상태로 변경한다.
def close(self):
self.opend= False
print("인벤토리를 닫았습니다.")
class Weapone:
pass
sword = Weapone()
item_bag = Inventory()
#아이템 인벤토리를 연다.
item_bag.open()
#칼을 인벤토리에 넣어보자.
item_bag.put(sword)
#item_space 에 접근하여 뭐가 있는지 확인해보자.
print("인벤토리에 보유중인 아이템 : ",item_bag.item_space)
#인벤토리를 닫자
item_bag.close()
<결과>
인벤토리가 열렸습니다. 아이템을 넣을 수 있습니다.
아이템을 인벤토리에 넣었습니다.
인벤토리에 보유중인 아이템 : [<__main__.Weapone object at 0x000001FC6533D288>]
인벤토리를 닫았습니다.
Process finished with exit code 0
결과를 보면 알겠지만 'Inventory' 클래스의 item_bag 객체 안에 'Weapone' 클래스의 객체가 들어간 것으로 확인된다.
(item_space는 리스트 타입)
3. 상속(Inheritance)
상속은 어떠한 클래스가 다른 클래스의 메서드, 속성을 물려받을 수 있는 것을 말한다. 물려받는다의 이름처럼 부모, 자식 간의 관계라고 생각하여 물려주는 클래스는 '부모 클래스', 물려받는 클래스는 '자식 클래스(=하위 클래스)'라고 한다.
다시 게임 아이템 무기 클래스로 돌아가 보자. 무기 클래스는 공통적으로 어떤 타입인지?, 어떤 종류의 무기인지라는 속성을 가지고 있다. 무기 중 Sword(검)은 무기 클래스에 속하는 또 다른 클래스로 정의할 수 있다.
(왜냐면 검은 무기의 특성을 그대로 가지고 있으니까)
클래스 상속 선언은 아래와 같다. 아래 예시 코드를 보면 쉽게 이해할 수 있다.
* Class 상속 사용법
Class 'Class명'('상속받을 Class명') :
# 무기 클래스 선언
class Weapone:
def __init__(self, type, name):
self.type = type
self.name = name
print("저는 무기 클래스입니다! 공격할 수 있습니다!!")
#무기의 종류를 출력하는 메소드
def what_weapone(self):
print("어떤 타입이야? :", self.type)
print("어떤 무기야? : ", self.name)
#Sword라는 클래스를 선언하고 Weapone 클래스를 상속한다.
class Sword(Weapone):
pass
#Sword 클래스 객체 선언
short_sword = Sword("근거리", "단검")
#부모 클래스의 메소드인 what_weapone() 호출
short_sword.what_weapone()
<결과>
저는 무기 클래스입니다! 공격할 수 있습니다
어떤 타입이야? : 근거리
어떤 무기야? : 단검
Process finished with exit code 0
코드를 보면 Sword라는 클래스에는 속성이나 메서드 등 어떤 것도 정의되어있지 않지만 Weapone 클래스를 상속함으로써 Weapone 클래스의 메서드를 그대로 호출할 수 있다.
그럼 왜 상속을 해야 하는가는 아래 2가지로 정리해보았다.
이유1 : 기존 클래스를 그대로 유지하기 위해 기존 클래스를 그대로 유지하고 기능을 추가하거나 기존 기능을 변경하려 할 때 사용한다. 이유2 : 코드 관리의 편의성을 위해 클래스별로 각각 메소드와 속성을 작성해놓으면 공통적인 내용 수정이 필요할 때 클래스마다 각각 수정해야 한다. 공통적인 부분에 대해 하나의 클래스로 정의하고 상속하는 방식으로 관리하면 수정이 편해진다. |
다음 포스팅은 다중 상속, 메서드 오버 라이딩 등의 개념에 대해서 정리해보려고 한다.
참고자료 1 : 아무튼 워라벨 hleecaster.com/python-class/
참고자료 2 : 위키 독스 - '점프 투 파이썬' wikidocs.net/28
참고자료 3 : 위키 독스 - '왕초보를 위한 파이썬' wikidocs.net/8
'코딩 > Python' 카테고리의 다른 글
[Python/파이썬] Class(클래스) 메서드 self 설명 (0) | 2021.03.27 |
---|---|
[Python/파이썬] Class(클래스) 기초 정리 - 4 : 추상 클래스, 클래스 변수 (0) | 2021.03.22 |
[Python/파이썬] Class(클래스) 기초 정리 - 3 : 다중상속, super().__init__(), 메서드 오버라이딩 (0) | 2021.03.21 |
[Python/파이썬] Class(클래스) 기초 정리 - 1 : 개념, 사용법 (0) | 2021.03.14 |
[Python/파이썬] PyQT5 및 QT Designer 소개, .ui 파일 .py로 변환 방법 (0) | 2021.03.06 |