Today I Learned (2024-07-20) 🤔
목차
오늘 공부한 내용 🧑🏻💻
- 인프런 나도코딩 8장 클래스 섹션 강의 듣기
1. 인프런(나도코딩, 파이썬)
메서드
- 메서드를 만들고 사용하는 방법
상속(inheritance)
부모 클래스에서 자식클래스를 만들어서 상속하는 방법
# 상속 # 일반 유닛 class Unit: def __init__(self, name, hp): self.name = name self.hp = hp # 공격 유닛 (Unit 을 상속 받는다.) class AttackUnit(Unit): def __init__(self, name, hp, damage): Unit.__init__(self, name, hp) # 부모의 name, hp 를 상속 받는다. self.damage = damage def attack(self, location): print( "{0}:{1} 방향으로 적군을 공격합니다. [공격력 {2}]".format( self.name, location, self.damage ) ) def damaged(self, damage): print("{} : {} 데미지를 입었습니다.".format(self.name, damage)) self.hp -= damage print("{} : 현재 체력은 {} 입니다.".format(self.name, self.hp)) if self.hp <= 0: print("{} : 파괴었습니다.".format(self.name)) # 메딕 : 의무병 # 파이어뱃 : 공격 유닛, 화염방사기 firebat1 = AttackUnit("파이어뱃", 50, 16) firebat1.attack("5시") # 공격 2번을 받는다고 가정 firebat1.damaged(25) firebat1.damaged(25)
다중상속
하나의 클래스가 둘 이상의 클래스를 상속받는 것
아래의 코드는
Unit
->AttackUnit
,Flyable
->FlyableAttackUnit
을 상속받아서valkyrie
라는 인스턴스를 만드는 코드이다.Unit
을 상속받아서AttackUnit
을 만든다.Flyable
클래스를 만든다.AttackUnit
과Flyable
클래스를 상속받은FlyableAttackUnit
을 만든다.
# 다중상속 # 일반 유닛 (부모 클래스) class Unit: def __init__(self, name, hp): self.name = name self.hp = hp # 공격 유닛 (Unit 을 상속 받는다.) # 자식 클래스 class AttackUnit(Unit): def __init__(self, name, hp, damage): Unit.__init__(self, name, hp) # 부모의 name, hp 를 상속 받는다. self.damage = damage def attack(self, location): print( "{0}:{1} 방향으로 적군을 공격합니다. [공격력 {2}]".format( self.name, location, self.damage ) ) def damaged(self, damage): print("{} : {} 데미지를 입었습니다.".format(self.name, damage)) self.hp -= damage print("{} : 현재 체력은 {} 입니다.".format(self.name, self.hp)) if self.hp <= 0: print("{} : 파괴었습니다.".format(self.name)) # 드랍쉽 : 공중 유닛, 수송기, 마린/ 파이버뱃 / 탱크 등을 수송, 공격 기능 X # 날 수 있는 기능을 가진 클래스 class Flyable: def __init__(self, flying_spped): self.flying_speed = flying_spped 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시")
메서드 오버라이딩
부모 클래스에서 정의한 메서드를 자식 클래스에서 중복 정의한다.
오버로딩 vs 오버라이딩
- 오버로딩(overloading) : 함수의 중복정의
- 오버라이딩(overriding) : 함수의 재정의
아래의 코드에서는
Unit
에서 만든 move 를FlyableAttackUnit
에서move
라는 메서드를 중복정의해서 새로운move
라는 매서드를 만들어서 호출한다.# 다중상속 # 일반 유닛 (부모 클래스) class Unit: def __init__(self, name, hp, speed): self.name = name self.hp = hp self.speed = speed def move(self, location): print("[지상 유닛 이동]") print( "{} : {} 방향으로 이동합니다. [속도 {}]".format( self.name, location, self.speed ) ) # 공격 유닛 (Unit 을 상속 받는다.) # 자식 클래스 class AttackUnit(Unit): def __init__(self, name, hp, speed, damage): Unit.__init__(self, name, speed,damage) # 부모의 name, hp 를 상속 받는다. self.damage = damage def attack(self, location): print( "{0}:{1} 방향으로 적군을 공격합니다. [공격력 {2}]".format( self.name, location, self.damage ) ) def damaged(self, damage): print("{} : {} 데미지를 입었습니다.".format(self.name, damage)) self.hp -= damage print("{} : 현재 체력은 {} 입니다.".format(self.name, self.hp)) if self.hp <= 0: print("{} : 파괴었습니다.".format(self.name)) # 드랍쉽 : 공중 유닛, 수송기, 마린/ 파이버뱃 / 탱크 등을 수송, 공격 기능 X # 날 수 있는 기능을 가진 클래스 class Flyable: def __init__(self, flying_spped): self.flying_speed = flying_spped 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, 0) # 지상 speed 0 Flyable.__init__(self, flying_speed) def move(self, location): print("[공중 유닛 이동]") self.fly(self.name,location) # 벌쳐 : 지상 유닛, 기동성이 좋음 vulture = AttackUnit("벌쳐",80, 10, 20) # 배틀크루저 : 공중 유닛, 체력도 굉장히 좋음, 공격력도 좋음 battlecrusier = FlyableAttackUnit("배틀크루저", 500,25, 3) vulture.move("11시") battlecrusier.move("9시")
pass
코드는 필요하지만, 아무 작업도하지 않기를 원할 때 사용된다.
나중에 코드를 추가 할 계획이거나 , 예외가 발생했을 때 처리하되, 아무 수행을 하지 않고 무시하는 데 사용할 수 있다.
아래 코드에서는
Unit
을 상속받아BuildingUnit
이라는 새로운 클래스를 만들고 생성자를 선언하고pass
를 작성했다.BuildingUnit
클래스를 이용해서supply_depot
을 생성했지만 아무것도 출력되지 않는다.
game_start()
와game_over()
메서드를 만들고game_start()
는 알림을 출력하고game_over
는pass
만 작성했다.- 코드를 실행 시
game_start
의 알림만 출력됐다.
# 건물 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()
[알림] : 새로운 게임을 시작합니다.
- 코드를 실행 시
super()
자식 클래스에서 부모클래스의 내용을 사용하고 싶을경우 사용한다.
🚨 주의할 점 : 2개 이상의 클래스를 상속받을 때는 첫 번째 상속 받은 클래스에 대해서만 Init 함수가 호출된다.
아래의 코드에서는
Unit
클래스와Flyable
클래스를 상속 받은FlyableUnit
이라는 클래스를 만들었지만, super() 로 생성자를 불러오면 제일 처음 상속 받은 클래스의 생성자만 호출된다.즉, 2개 이상의 클래스를 상속받아 생성자를 사용하고 싶다면 상속 받은 클래스들의
init
을 모두 호출해준다.# 다중상속 super() 의 문제점 # 2개 이상의 클래스를 상속받을 때는 첫 번째 상속 받은 클래스에 대해서만 Init 함수가 호출된다. class Unit: def __init__(self): print("유닛 생성자") class Flyable: def __init__(self): print("Flyable 생성자") class FlyableUnit(Unit, Flyable): def __init__(self): # super().__init__() Unit.__init__(self) Flyable.__init__(self) # 드랍쉽 dropship = FlyableUnit()
어려웠던 내용 📚
- 다중 상속에서 super()를 사용할 때 첫 번째 상속 클래스의 생성자만 호출되는 점을 주의해야겠다.
궁금한 내용과 부족한 내용 🙋🏻
- 다중 상속 시 super()를 효율적으로 사용하는 방법에 대해 더 알고 싶다.
- MRO(Method Resolution Order) : 다중 상속 시 메서드나 속성을 어떤 순서로 검색할지를 결정하는 규칙을 의미한다.
- 다중 상속에서 메서드 호출 순서를 명확하게 이해 하는데 필수적이다. 참고사이트(Python MRO란?)
- MRO(Method Resolution Order) : 다중 상속 시 메서드나 속성을 어떤 순서로 검색할지를 결정하는 규칙을 의미한다.
MRO
에 대해서는 따로 글을 작성하면 좋을 것 같다.
느낀 점 💡
- 상속과 다중 상속에 대해 다시 공부했다.
- 오버로딩과 오버라이딩에 대해 다시 공부했다.
'TIL (2024) > 2024.07' 카테고리의 다른 글
[TIL] 2024-07-22 (2) | 2024.07.23 |
---|---|
[TIL] 2024-07-21 (0) | 2024.07.21 |
[TIL] 2024-07-19 (0) | 2024.07.20 |
[TIL] 2024-07-18 (3) | 2024.07.19 |
[TIL] 2024-07-17 (0) | 2024.07.17 |
배움에 즐거움을 느끼는 마네의 연구소입니다. 이미지 출처 : https://www.instagram.com/hoseobiiiiiii._.0410/
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!