: class 내 정의된 함수
# 기존 생성되어 있던 일반 유닛 외 공격 유닛 class 를 생성한다.
- class 명 : AttackUnit
- Unit 을 생성할 때와 동일하게 name, hp, damage 를 변수로 받는다.
- 아래 조건의 함수들을 추가한다.
- 공격 유닛은 attack(location) 값을 통해 특정 위치를 공격 할 수 있다.
- damaged 함수를 통해 공격을 받을 경우, 체력(hp)가 감소하며, 0 이하 일 경우, 파괴된다.
# 일반 유닛
class Unit:
def __init__(self, name, hp, damage):
self.name = name
self.hp = hp
self.damage =damage
print("{0} 유닛이 생성되었습니다." .format(self.name))
print("체력 {0}, 공격력 {1}\n" .format(self.hp, self.damage))
# 공격 유닛
class AttackUnit:
def __init__(self, name, hp, damage): # self.* 는 자기 자신을 의미, 클래스 내에서 메소드 앞에 self를 입력 자기자신의 변수에 접근 가능
self.name = name # 여기서 우측의 name 은 전달 받은 파라미터 값
self.hp = hp
self.damage =damage
def attack(self, location):
print("{0} : {1} 방향으로 적군을 공격합니다.[공격력 {2}]" .format(self.name, location, self.damage))
def damaged(self, damage):
print("{0} : {1} 데미지를 입었습니다." .format(self.name, damage))
self.hp -= damage
print("{0} : 현재 체력은 {1} 입니다." .format(self.name, self.hp))
if self.hp <= 0:
print("{0} : 파괴되었습니다." .format(self.name))
# 실제 파이어뱃 생산 및 공격, 피해 시나리오
# 공격 유닛
class AttackUnit:
def __init__(self, name, hp, damage): # self.* 는 자기 자신을 의미, 클래스 내에서 메소드 앞에 self를 입력 자기자신의 변수에 접근 가능
self.name = name # 여기서 우측의 name 은 전달 받은 파라미터 값
self.hp = hp
self.damage =damage
def attack(self, location):
print("{0} : {1} 방향으로 적군을 공격합니다.[공격력 {2}]" .format(self.name, location, self.damage))
def damaged(self, damage):
print("{0} : {1} 데미지를 입었습니다." .format(self.name, damage))
self.hp -= damage
print("{0} : 현재 체력은 {1} 입니다." .format(self.name, self.hp))
if self.hp <= 0:
print("{0} : 파괴되었습니다." .format(self.name))
# 파이어뱃 : 공격 유닛, 화염 방사기.
firebat1 = AttackUnit("파이어뱃", 50, 16)
firebat1.attack("5시")
#공격 2번 받는다고 가정
firebat1.damaged(25)
firebat1.damaged(25)
'''결과 값 :
파이어뱃 : 5시 방향으로 적군을 공격합니다.[공격력 16]
파이어뱃 : 25 데미지를 입었습니다.
파이어뱃 : 현재 체력은 25 입니다.
파이어뱃 : 25 데미지를 입었습니다.
파이어뱃 : 현재 체력은 0 입니다.
파이어뱃 : 파괴되었습니다.
'''
: 다른 class( 부모 class 라고 부름) 에서 필요한 파라미터 들을 전달 받아(상속) 자식 class 에서 사용하게 되는 것.
-> class 간 중복되어 사용되는 항목이 있을 경우, 사용
# 매딕 : 의무병 / 공격력 없음
매딕의 경우, 공격력이 없는 일반 유닛이므로, 일반 유닛 클래스의 damage 항목을 없애고, 공격 유닛 클래스에서 damage를 설정한다.
기존 공격 유닛의 경우, name, hp, damage 가 일반 유닛과 중복되므로, 위의 코딩을 아래와 같이 변경 할 수 있다.
- class 자식class(부모class) 형태로 표기.
- __init__ 함수내 상속 받는 항목에 대해 초기화를 진행해줌
ex) Unit.__init__(self, name, hp)
# 일반 유닛
class Unit: # 대소문자 구분함
def __init__(self, name, hp):
self.name = name
self.hp = hp
# 공격 유닛
class AttackUnit(Unit): # () 안에 상속 받고 싶은 class 입력
def __init__(self, name, hp, damage): # self.* 는 자기 자신을 의미, 클래스 내에서 메소드 앞에 self를 입력 자기자신의 변수에 접근 가능
Unit.__init__(self, name, hp) # Unit 에서 공통으로 받는 값
self.damage =damage
def attack(self, location):
print("{0} : {1} 방향으로 적군을 공격합니다.[공격력 {2}]" .format(self.name, location, self.damage))
def damaged(self, damage):
print("{0} : {1} 데미지를 입었습니다." .format(self.name, damage))
self.hp -= damage
print("{0} : 현재 체력은 {1} 입니다." .format(self.name, self.hp))
if self.hp <= 0:
print("{0} : 파괴되었습니다." .format(self.name))
# 파이어뱃 : 공격 유닛, 화염 방사기.
firebat1 = AttackUnit("파이어뱃", 50, 16)
firebat1.attack("5시")
#공격 2번 받는다고 가정
firebat1.damaged(25)
firebat1.damaged(25)
''' 결과 값 :
파이어뱃 : 5시 방향으로 적군을 공격합니다.[공격력 16]
파이어뱃 : 25 데미지를 입었습니다.
파이어뱃 : 현재 체력은 25 입니다.
파이어뱃 : 25 데미지를 입었습니다.
파이어뱃 : 현재 체력은 0 입니다.
파이어뱃 : 파괴되었습니다.
'''
: 2개 이상의 부모 class를 갖는 것.
지상 유닛 외, 비행이 가능한 유닛들에 관한 class 를 생성
- 비행 기능만 있는 class = Flyable
# 드랍쉽 : 공중 유닛, 수송기. 마린 / 파이어뱃 / 탱크 등을 수송. 공격 X
드랍쉽 등 비행은 가능하나, 공격 기능이 없는 유닛의 경우, Flyable class 를 통해 유닛 생성 가능.
# 발키리 : 공중 유닛, 한번에 14발 미사일 발사. / 비행 + 공중 공격 속성을 가짐
비행 + 공중 공격이 가능한 클래스를 생성(FlyableAttackUnit)
Flyable 과 AttackUnit 2개의 class 에서 상속을 받음.
class FlyableAttackUnit(AttackUnit, Flyable):
# 일반 유닛
class Unit: # 대소문자 구분함
def __init__(self, name, hp):
self.name = name
self.hp = hp
# 공격 유닛
class AttackUnit(Unit): # () 안에 상속 받고 싶은 class 입력
def __init__(self, name, hp, damage):
Unit.__init__(self, name, hp) # Unit 에서 공통으로 받는 값
self.damage =damage
def attack(self, location):
print("{0} : {1} 방향으로 적군을 공격합니다.[공격력 {2}]" .format(self.name, location, self.damage))
def damaged(self, damage):
print("{0} : {1} 데미지를 입었습니다." .format(self.name, damage))
self.hp -= damage
print("{0} : 현재 체력은 {1} 입니다." .format(self.name, self.hp))
if self.hp <= 0:
print("{0} : 파괴되었습니다." .format(self.name))
# 날 수 있는 기능을 가진 클래스
class Flyable:
def __init__(self, flying_speed):
self.flying_speed = flying_speed
def fly(self, name, location):
print("{0} : {1} 방향으로 날아갑니다. [속도 {2}]" .format(name, location, self.flying_speed))
# 드랍쉽 : 공중 유닛, 수송기. 마린 / 파이어뱃 / 탱크 등을 수송. 공격 X
# 공중 공격 유닛 클래스
class FlyableAttackUnit(AttackUnit, Flyable):
def __init__(self, name, hp, damage, flying_speed):
AttackUnit.__init__(self, name, hp, damage)
Flyable.__init__(self, flying_speed)
# # 발키리 : 공중 유닛, 한번에 14발 미사일 발사.
valkyrie = FlyableAttackUnit("발키리", 200, 6, 5)
valkyrie.fly(valkyrie.name, "3시")
# 결과 값 : 발키리 : 3시 방향으로 날아갑니다. [속도 5]
: 자식 클래스에서 정의한 매소드 사용
# 일반 유닛 - speed 추가
class Unit: # 대소문자 구분함
def __init__(self, name, hp, speed):
self.name = name
self.hp = hp
self.speed = speed
def move(self, location):
print("[지상 유닛 이동]")
print("{0} : {1} 방향으로 이동합니다. [속도 : {2}]" .format(self.name, location, self.speed))
# 공격 유닛
class AttackUnit(Unit): # () 안에 상속 받고 싶은 class 입력 / speed 추가
def __init__(self, name, hp, speed, damage):
Unit.__init__(self, name, hp, speed) # Unit 에서 공통으로 받는 값, speed가 추가됨
self.damage =damage
def attack(self, location):
print("{0} : {1} 방향으로 적군을 공격합니다.[공격력 {2}]" .format(self.name, location, self.damage))
def damaged(self, damage):
print("{0} : {1} 데미지를 입었습니다." .format(self.name, damage))
self.hp -= damage
print("{0} : 현재 체력은 {1} 입니다." .format(self.name, self.hp))
if self.hp <= 0:
print("{0} : 파괴되었습니다." .format(self.name))
# 날 수 있는 기능을 가진 클래스
class Flyable:
def __init__(self, flying_speed):
self.flying_speed = flying_speed
def fly(self, name, location):
print("{0} : {1} 방향으로 날아갑니다. [속도 {2}]" .format(name, location, self.flying_speed))
# 공중 공격 유닛 클래스
class FlyableAttackUnit(AttackUnit, Flyable):
def __init__(self, name, hp, damage, flying_speed):
AttackUnit.__init__(self, name, hp, 0, damage) # 지상 speed = 0 , flying_speed 값이 있음
Flyable.__init__(self, flying_speed)
# 벌쳐 : 지상 유닛, 기동성이 좋음
vulture = AttackUnit("벌처", 80, 10, 20)
# 배틀크루저 : 공중 유닛, 체력도 굉장히 좋음, 공격력도 좋음.
battlecruiser = FlyableAttackUnit("배틀크루저", 500, 25, 3)
vulture.move("11시")
battlecruiser.fly(battlecruiser.name, "9시")
''' 결과 값 :
[지상 유닛 이동]
벌처 : 11시 방향으로 이동합니다. [속도 : 10]
배틀크루저 : 9시 방향으로 날아갑니다. [속도 3]
'''
- 일반 유닛에도 speed 값을 할당하고,
- 위와 같이 내용을 구성 할 수 있으나,
이동이 필요할 경우, 지상유닛은 move, 공중유닛은 fly를 구분하여 사용해야 하는 번거로움이 있다.
# 매서드 오버라이딩(자식 클래스에서 함수 저장) 하여 해당 코딩을 move로 통일 시켜 줄 수 있다.
# FlyableAttackUnit Class 내에 move 함수 추가.
# 일반 유닛
class Unit: # 대소문자 구분함
def __init__(self, name, hp, speed):
self.name = name
self.hp = hp
self.speed = speed
def move(self, location):
print("[지상 유닛 이동]")
print("{0} : {1} 방향으로 이동합니다. [속도 : {2}]" .format(self.name, location, self.speed))
# 공격 유닛
class AttackUnit(Unit): # () 안에 상속 받고 싶은 class 입력 / speed 추가
def __init__(self, name, hp, speed, damage):
Unit.__init__(self, name, hp, speed)
self.damage =damage
def attack(self, location):
print("{0} : {1} 방향으로 적군을 공격합니다.[공격력 {2}]" .format(self.name, location, self.damage))
def damaged(self, damage):
print("{0} : {1} 데미지를 입었습니다." .format(self.name, damage))
self.hp -= damage
print("{0} : 현재 체력은 {1} 입니다." .format(self.name, self.hp))
if self.hp <= 0:
print("{0} : 파괴되었습니다." .format(self.name))
# 날 수 있는 기능을 가진 클래스
class Flyable:
def __init__(self, flying_speed):
self.flying_speed = flying_speed
def fly(self, name, location):
print("{0} : {1} 방향으로 날아갑니다. [속도 {2}]" .format(name, location, self.flying_speed))
# 공중 공격 유닛 클래스
class FlyableAttackUnit(AttackUnit, Flyable):
def __init__(self, name, hp, damage, flying_speed):
AttackUnit.__init__(self, name, hp, 0, damage) # 지상 speed = 0 , flying_speed 값이 있음
Flyable.__init__(self, flying_speed)
def move(self, location):
print("[공중 유닛 이동]")
self.fly(self.name, location)
# 벌쳐 : 지상 유닛, 기동성이 좋음
vulture = AttackUnit("벌처", 80, 10, 20)
# 배틀크루저 : 공중 유닛, 체력도 굉장히 좋음, 공격력도 좋음.
battlecruiser = FlyableAttackUnit("배틀크루저", 500, 25, 3)
vulture.move("11시")
battlecruiser.move("9시")
''' 결과 값 :
[지상 유닛 이동]
벌처 : 11시 방향으로 이동합니다. [속도 : 10]
[공중 유닛 이동
배틀크루저 : 9시 방향으로 날아갑니다. [속도 3]
'''
이전 코딩과 비교 시, class FlyableAttackUnit 내에 def move 를 추가하여,
공중 유닛도 move 함수로 사용할 수 있게 된다.
변경 전 | 변경 후 |
class 코딩 : class FlyableAttackUnit(AttackUnit, Flyable): def __init__(self, name, hp, damage, flying_speed): AttackUnit.__init__(self, name, hp, 0, damage) Flyable.__init__(self, flying_speed) |
class 코딩 : class FlyableAttackUnit(AttackUnit, Flyable): def __init__(self, name, hp, damage, flying_speed): AttackUnit.__init__(self, name, hp, 0, damage) # 지상 speed = 0 , flying_speed 값이 있음 Flyable.__init__(self, flying_speed) def move(self, location): print("[공중 유닛 이동") self.fly(self.name, location) |
호출 코딩 : vulture.move("11시") battlecruiser.fly(battlecruiser.name, "9시") |
호출 코딩 : vulture.move("11시") battlecruiser.move("9시") |
결과 값 : [지상 유닛 이동] 벌처 : 11시 방향으로 이동합니다. [속도 : 10] 배틀크루저 : 9시 방향으로 날아갑니다. [속도 3] |
결과 값 : [지상 유닛 이동] 벌처 : 11시 방향으로 이동합니다. [속도 : 10] [공중 유닛 이동] 배틀크루저 : 9시 방향으로 날아갑니다. [속도 3] |
* def 내 print("[공중 유닛 이동]") 제거 시, 동일한 내용 출력 가능.
: 실제 정상적으로 코딩된 것 처럼 처리.
# 건물을 지을 경우,
# 일반 유닛
class Unit:
def __init__(self, name, hp, speed):
self.name = name
self.hp = hp
self.speed = speed
def move(self, location):
print("[지상 유닛 이동]")
print("{0} : {1} 방향으로 이동합니다. [속도 : {2}]" .format(self.name, location, self.speed))
# 건물 클래스
class BuildingUnit(Unit):
def __init__(self, name, hp, location):
pass # 정상적으로 작성된 것 처럼 동작
# 서플라이 디폿 : 건물, 1개 건물 = 8 유닛.
supply_depot = BuildingUnit("서플라이 디폿", 500, "7시") # 정상동작
def game_start():
print("[알림] 새로운 게임을 시작합니다.")
def game_end():
pass
game_start()
game_end()
# 결과 값 : [알림] 새로운 게임을 시작합니다.
BuildingUnit 의 클래스 내부 매서드 및 gate_end 함수의 경우, 실제 코딩을 작성하지 않고, pass라고 입력하여
코딩 내용과 상관없이 정상동작하는 듯한 역할을 보여줄 수 있다.
: 상속 받는 기능으로 사용하나, 다중 상속 시 차이가 발생한다.
-> 첫번째 클래스만 상속 받음.
: 대신 self를 사용하지 않아 단일 상속 시에는 간략하게 사용할 수 있다.
# 기존 상속 방법
#건물
class BuildingUnit(Unit):
def __init__(self, name, hp, location):
Unit.__init__(self, name, hp, 0) # 을 super를 사용하여 변경할 경우
self.location = location
# super 사용
#건물
class BuildingUnit(Unit):
def __init__(self, name, hp, location):
super().__init__(name, hp, 0) # 괄호를 붙이고 self 를 제외한다. # 다중상속 시 차이가 남
self.location = location
위의 두 코딩은 같은 결과 값을 산출한다.
# 다중 상속 시 차이점을 확인하기 위해 부모 클래스를 간략히 재구성해보면
case 1. class FlyableUnit(Unit, Flyable):
class Unit:
def __init__(self):
print("Unit 생성자")
class Flyable:
def __init__(self):
print("Flyable 생성자")
class FlyableUnit(Unit, Flyable):
def __init__(self):
super().__init__()
# 드랍쉽
dropship = FlyableUnit() #을 출력할 경우, super가 다중상속을 받으면 앞의 class만 상속받음. 다중상속시에는 Unit.__init__(self) 와 Flyable.__init__(self) 를 적용
# 결과 값 : Unit 생성자
case 2. class FlyableUnit(Flyable, Unit):
class Unit:
def __init__(self):
print("Unit 생성자")
class Flyable:
def __init__(self):
print("Flyable 생성자")
class FlyableUnit(Flyable, Unit):
def __init__(self):
super().__init__()
# 드랍쉽
dropship = FlyableUnit() #을 출력할 경우, super가 다중상속을 받으면 앞의 class만 상속받음. 다중상속시에는 Unit.__init__(self) 와 Flyable.__init__(self) 를 적용
# 결과 값 : Flyable 생성자
case 1과 2 가 super로 상속 받을 경우, 앞쪽에 상속받는 클래스에 대한 값만 상속 받아 2 코딩의 결과 값이 다르게 나타난다. 다중상속시에는 사용을 피해야한다.
유튜버 '나도코딩' 님의 영상을 보며 공부 및 노트 작성합니다.
함께 공부해 나가실 분은
www.youtube.com/watch?v=kWiCuklohdY&feature=youtu.be
[Python 파이썬 독학 8일차] (0) | 2020.10.04 |
---|---|
[Python 파이썬 독학 7-3일차] (0) | 2020.09.30 |
[Python 파이썬 독학 7-1일차] (0) | 2020.09.28 |
[Python 파이썬 독학 자가 점검] (0) | 2020.09.26 |
[Python 파이썬 독학 6일차] (0) | 2020.09.25 |
댓글 영역