Language/Python

객체와 클래스.

Return 2021. 6. 21. 21:52

객체

파이썬의 모든것은 객체입니다. 객체는 데이터(변수(속성)) , 코드(함수(메소드))를 모두 포함합니다. 

 

객체를 생성하려면 클래스를 먼저 만들어야합니다.! 먼저 빈 클래스 하나를 만들어 볼까요?

class Person():  
    pass
        
someone = Person()

특별한 파이썬 객체 초기화 메소드  :  __init__

class Person():
    def __init__(self): #self는 객체 자신을 가리킨다.
        pass

이제 매개변수를 하나 추가해 봅시다.!

이제 name 매개변수에 문자열을 전달하여 Person클래스로부터 객체를 생성할 수 있습니다.

class Person():
    def __init__(self,name):
        self.name = name

hunter = Person('Mr.Lee') 

* 모든 클래스 정의에서 __init__ 메서드 가질 필요는 없습니다. __init__메서드는 같은 클래스에서 생성된 다른 객체를 구분하기 위함입니다.! 

 

상속

기존 클래스에서 일부를 추가허거나 변경하여 새 클래스를 생성합니다. 필요한 것만 추가/변경하여 새클래스를 정의합니다.

class Car():
    def exclaim(self):
        print("I'm Car!")

class Yugo(Car):
     pass
car = Car()
car_yugo = Yugo()
car.exclaim()
# I'm Car!
car_yugo.exclaim() 
# I'm Car!

Car로부터 exclaim()메소드를 상속받았다. 하지만 yugo는 자신이 Car라고 말하고있습니다.! >> 정체성 모호!?

 

메소드 오버라이드

Yugo에 대한 exclaim()메소드를 어떻게 바꿀까요?

class Car():
    def exclaim(self):
        print("I'm a Car")
        
 class Yugo(Car):
    def exclaim(self):
        print("i'm a Yugo!")
        
car = Car()
car_yugo = Yugo()   

car_yugo.exclaim() ##i'm a Yugo!
car.exclaim() #I'm a Car

부모에게 도움 받기 : super

자식클래스에서 부모 클래스를 호출하고 싶다면 super()메소드를 사용합니다.!

class Person():
    def __init__(self,name):
        self.name = name
        
class EmailPerson(Person):
    def __init__(self,name,email):
        super().__init__(name)
        self.email = email

자식클래스에서 init메서드를 정의하면 부모클래스의 init메소드를 대체하는 것이기 때문에 더 이상 자동으로 부모 클래스의 init메서드가 호출되지 않습니다. 그러므로 이것을 명시적으로 호출해야 합니다.!

 

 

이정도로 객체의 기본 개념을 마무리하고

자료를 찾아보다 어떤 분께서 스타그래프게임을 활용해 클래스를 잘 설명하여서 한번 더 살펴보도록 하겠습니다.!

class Unit:
    def __init__(self,name,hp,damage):
        self.name = name
        self.hp = hp
        self.damage = damage
        print("{}유닛이 생성되었습니다.".format(self.name))
        print("체력{} 공격력{}".format(self.hp,self.damage))
        
marine1 = Unit("마린",100,10)
marine2 = Unit("마린",100,10)
tank = Unit("탱크",200,20)

위 코드의 출력결과

클래스의 멤버 변수를 외부에서도 사용할수 있습니다.

wraith = Unit("레이스",80,5)
print("유닛 이름 : {} 공격력 : {}".format(wraith.name,wraith.damage))

 

상속을 이용한 스타그래프트 클래스 예제(상속)

상속시 __init__를 유의깊게 봐주세요!

class Unit:
    def __init__(self, name, hp):
        # 멤버 변수 class 내에서 정의된 변수
        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):
        print("{}:{} 방향으로 적군을 공격 합니다. [공격력 : {}]".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))
            
#파이어뱃 공격유닛 , 화염방사기 
firebat = AttackUnit("파이어뱃",50,20)
firebat.attack("10시")

firebat.damaged(25)
firebat.damaged(25)

다중상속

class Unit:
    def __init__(self, name, hp):
        # 멤버 변수 class 내에서 정의된 변수
        self.name = name
        self.hp = hp
        
class AttackUnit(Unit):   #공격유닛은 유닛클래스를 상속받았다.
    def __init__(self, name, hp, damage):
        # 멤버 변수 class 내에서 정의된 변수
        Unit.__init__(self,name,hp)
        self.damage = damage

    def attack(self,location):
        print("{}:{} 방향으로 적군을 공격 합니다.[공격력 {}]".format(self.name,location,self.damage)) #self는 자기자신의 멤버 변수를 쓴다. self없는 location은 전달받은 값을 쓴다.

    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))
            
            
class Flyable:
    def __init__(self,flying_speed):
        self.flying_speed = flying_speed
        
    def fly(self,name,location):
        print("{} : {} 방향으로 날아갑니다. [속도 : {}]".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)
        

valkyrie = FlyableAttackUnit("발키리",200,5,10)
valkyrie.fly(valkyrie.name , "3시")

 

연산자 오버로딩 

Unit 클래스의 move메소드와 FlyableAttackUnit 클래스의 move 메소드.

class Unit:
    def __init__(self, name, hp,speed):  #speed 맴버 변수 추가
        # 멤버 변수 class 내에서 정의된 변수
        self.name = name
        self.hp = hp
        self.speed = speed

    def move(self,location):
        print("[지상 유닛 이동]")
        print("{} : {} 방향으로 이동합니다. [속도 {}]".format(self.name,location,self.speed))

class AttackUnit(Unit):   #공격유닛은 유닛클래스를 상속받았다.
    def __init__(self, name, hp,speed, damage):
        # 멤버 변수 class 내에서 정의된 변수
        Unit.__init__(self,name,hp,speed)
        self.damage = damage

    def attack(self,location):
        print("{}:{} 방향으로 적군을 공격 합니다.[공격력 {}]".format(self.name,location,self.damage)) #self는 자기자신의 멤버 변수를 쓴다. self없는 location은 전달받은 값을 쓴다.

    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))


#드랍쉽 : 공중 유닛,수송기,마린/파이어뱃.탱크 등 수송 기능 공격 불가
#날수 있는 기능을 가진 클래스
class Flyable:
    def __init__(self,flying_speed):
        self.flying_speed = flying_speed

    def fly(self,name,location):
        print("{} : {} 방향으로 날아갑니다. [속도 {}]".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으로 줌
        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시")