[Python] 상속
[Python] 상속
Inflearn Study
- 인프런에서 “파이썬 무료 강의 (기본편) - 6시간 뒤면 나도 개발자” 강의를 들으며 혼자 공부한 내용입니다.
상속
- 부모 클래스와 자식 클래스가 존재하며 부모 클래스의 멤버를 자식 클래스가 물려받을 수 있습니다.
# 일반 유닛
class Unit:
    def __init__(self, name, hp): # 생성자
        self.name = name # 멤버 변수(클래스 내 생성된 변수)
        self.hp = hp
# 공격 유닛
class AttackUnit(Unit): # 상속
    def __init__(self, name, hp, damage): # 생성자
        Unit.__init__(self, name, hp)
        self.damage = damage
    
    def attack(self, location): # self는 따로 보내줄 필요 없음
        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 클래스 이름 ( 상속 받을 클래스 이름 )
- Unit.__init__(self, name, hp) : 명시적으로 Unit 클래스의 생성자를 호출하는 방법
    - 이 경우에는 self를 함께 전달해야 합니다.
 
다중 상속
- 두 개 이상의 클래스를 상속 받는 것
    - 하나의 자식 클래스가 두 개 이상의 부모 클래스를 가지는 것
 
# 드랍쉽 : 공중 유닛, 수송기, 미린/ 파이어뱃/ 탱크 등을 수송 공격 기능 x
# 날 수 있는 기능을 가진 클래스
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, damage)
        Flyable.__init__(self, flying_speed)
        
# 발키리 : 공중 공격 유닛, 한 번에 14발 미사일 발사
valkyrie = FlyableAttackUnit("발키리", 200, 6, 5)
valkyrie.fly(valkyrie.name,"3시")    
- AttackUnit.__init__(self, name, hp, damage) : 명시적으로 AttackUnit 클래스의 생성자를 호출하는 방법
- Flyable.__init__(self, flying_speed) : 명시적으로 Flyable 클래스의 생성자를 호출하는 방법
다중 상속 시 주의해야할 점 (super 사용)
- 다이아몬드 상속을 하는 경우
class Unit:
    def __init__(self): # 생성자
        print("Unit 생성자")
class UnitB(Unit):
    def __init__(self): # 생성자
        print("UnitB 생성자")
        Unit.__init__(self)
class UnitC(Unit):
    def __init__(self): # 생성자
        print("UnitC 생성자")
        Unit.__init__(self)
class UnitD(UnitB, UnitC):
    def __init__(self): # 생성자
        print("UnitB 생성자")
        UnitB.__init__(self)
        UnitC.__init__(self)
- UnitD의 인스턴트 객체를 생성하면 UnitB와 UnitC에서 Unit의 클래스가 두 번 호출됩니다.
- 이를 피하기 위해 super 라는 함수를 이용합니다.
    - super : 부모 클래스의 객체를 반환
 
class Unit:
    def __init__(self): # 생성자
        print("Unit 생성자")
class UnitB(Unit):
    def __init__(self): # 생성자
        print("UnitB 생성자")
        super.__init__(self)
class UnitC(Unit):
    def __init__(self): # 생성자
        print("UnitC 생성자")
        super.__init__(self)
class UnitD(UnitB, UnitC):
    def __init__(self): # 생성자
        print("UnitB 생성자")
        super.__init__(self)
- Unit의 클래스가 두 번 호출되는 것을 막아 줍니다.
메소드 오버라이딩 (Method Overriding)
: 상속의 개념 중 하나로 자식 클래스가 자신의 부모 클래스들 중 하나에 의해 이미 제공된 메소드를 특정한 형태로 구현하는 것입니다.
# 일반 유닛
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): # 상속
    def __init__(self, name, hp, speed, damage): # 생성자
        Unit.__init__(self, name, hp, speed)
        self.damage = damage
    
    def attack(self, location): # self는 따로 보내줄 필요 없음
        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))
# 드랍쉽 : 공중 유닛, 수송기, 미린/ 파이어뱃/ 탱크 등을 수송 공격 기능 x
# 날 수 있는 기능을 가진 클래스
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, 0, hp, damage)
        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시")
- Unit 클래스의 move 함수를 FlyableAttackUnit 클래스에서 재정의 하고있습니다.
- vulture.move(“11시”) 에서는 Unit 클래스의 move 함수대로 출력됩니다.
- battlecruiser.move(“9시”) 에서는 FlyableAttackUnit 클래스의 move 함수로 출력됩니다.
pass
# 일반 유닛
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))
# pass
# 건물
class BuildingUnit(Unit):
    def __init__(self, name, hp, location):
        pass # 아무것도 안하고 그냥 넘어갈거임
# 서플라이 디폿 : 건물, 1개 건물 = 8개 유닛
supply_depot = BuildingUnit("서플라이 디폿", 500, "7시")
def game_start():
    print("[알림] 새로운 게임을 시작합니다.")
def game_over():
    pass
game_start()
game_over()
- pass : 실행할 코드가 없다는 것으로 다음 행동을 계속해서 진행합니다.
- continue : 다음 순번의 loop를 강제로 돌도록 하는 것을 의미합니다.
 
      
    
Leave a comment