객체지향 프로그래밍을 사용하는 이유는 반복되는 함수의 부분을 하나로 묶어서 재사용성과 편리함을 위해서 만들어 졌다고 보면 될 것 같습니다.
객체지향 프로그래밍을 하기위해서 파이썬에서는 클래스를 사용하며 클래스안에는 __init__이라는 메서드를 사용하여 작성을 하나는데 __init__은 클래스를 통해 객체가 생성이 될 때에 자동적으로 호출이 되는 메서드이며 클래스의 인스턴스를 만들 때 초기화 작업을 하며 객체의 속성을 설정하거나 초기의 데이터(게임을 예시로 이름, 성별, HP, MP같은거?)를 받는 역할을 합니다.
class Character:
def __init__(self, name, health, armor):
self.name = name
self.health = health
self.armor = armor
# 코드의 구조화 및 캡슐화 - test 1
def damage(self, dmg):
# 방어구로 데미지 감소 처리
reduced_dmg = self._calculate_damage(dmg)
self._apply_damage(reduced_dmg)
def _calculate_damage(self, dmg):
# 방어구를 고려한 데미지 감소 계산
return dmg - self.armor
def _apply_damage(self, dmg):
self.health -= dmg
print(f"Received {dmg} damage. Health is now {self.health}.")
user = Character("billy", 100, 10)
user.damage(15) # test 1
print(f"당신의 이름은 : {user.name}") # 당신의 이름은 : billy
print(f"당신의 체력은 : {user.health}") # 당신의 체력은 : 95
print(f"당신의 방어력은 : {user.armor}") # 당신의 방어력은 : 10
위의 지식으로 간단한 객체지향 프로그래밍을 이용한 게임 캐릭터를 만들었는데.
위와 같이 정의 된 인스턴스에 맞추어 값을 저장 사용 할 수 있으며
user = Character("billy", 100, 10)
user.damage(15) # Received 5 damage. Health is now 95.
print(f"당신의 이름은 : {user.name}")
print(f"당신의 체력은 : {user.health}")
print(f"당신의 방어력은 : {user.armor}")
user2 = Character("jun", 150, 5)
user2.damage(15) # Received 10 damage. Health is now 140.
print(f"당신의 이름은 : {user2.name}") # 당신의 이름은 : jun
print(f"당신의 체력은 : {user2.health}") # 당신의 체력은 : 140
print(f"당신의 방어력은 : {user2.armor}") # 당신의 방어력은 : 5
같은 클래스에 다른 인스턴스를 만들어준다면 상관없이 각 인스턴스에는 영향을 주지 않고 사용을 할 수 있습니다.
user = Character("billy", 100, 10)
user.damage(15) # Received 5 damage. Health is now 95.
user2 = Character("jun", 150, 5)
user2.damage(15) # Received 10 damage. Health is now 140.
user.damage(40) # Received 30 damage. Health is now 65.
user.damage(20) # Received 10 damage. Health is now 55.
user2.damage(50) # Received 45 damage. Health is now 95.
print(f"당신의 이름은 : {user.name}") # 당신의 이름은 : billy
print(f"당신의 체력은 : {user.health}") # 당신의 체력은 : 55
print(f"당신의 방어력은 : {user.armor}") # 당신의 방어력은 : 10
print(f"당신의 이름은 : {user2.name}") # 당신의 이름은 : jun
print(f"당신의 체력은 : {user2.health}") # 당신의 체력은 : 95
print(f"당신의 방어력은 : {user2.armor}") # 당신의 방어력은 : 5
같은 메서드를 반복해서 실행 하는 것도 가능합니다.
여기서 코드의 구조화 및 캡슐화라는 부분에서 코드를 밖으로 노출 시키지 않고 사용을 하고 싶을 때에 사용을 하는 방법으로
class Character:
def __init__(self, name, health, armor):
self.name = name
self._health = health # 내부에서 _health로 저장
self.armor = armor
# 코드의 구조화 및 캡슐화 - test 1
def damage(self, dmg):
# 방어구로 데미지 감소 처리
reduced_dmg = self._calculate_damage(dmg)
self._apply_damage(reduced_dmg)
def _calculate_damage(self, dmg):
# 방어구를 고려한 데미지 감소 계산
return dmg - self.armor
def _apply_damage(self, dmg):
self._health -= dmg
print(f"Received {dmg} damage. Health is now {self._health}.")
# 속성처럼 접근 가능! test 2
@property
def health(self):
return self._health
@health.setter
def health(self, value):
# 유효성 검사 등 추가 가능
if value < 0:
self._health = 0
else:
self._health = value
def __str__(self):
return f"Character(Health: {self._health}, Armor: {self.armor})"
# 객체 생성
user = Character("billy", 100, 10)
user.damage(20) # test 1 - 체력에 데미지 적용
# 체력 확인
print(f"Current health: {user.health}") # 속성처럼 체력 확인 test 2
위와 같이 기존 인스턴스를 생성할 때에 health의 값을 self.health에 저장하는 것이 아닌 self._health에 저장을 하는데 이건 코드를 만드는 사람들 끼리의 약속 같은 거라고 한다.
이제 우리는 유저의 체력을 확인하고 싶으면 user._health를 쳐야하니만 그렇게 하는것이 아닌
@property를 이용하여 user.health를 쳤을 때 체력 값이 나올 수 있도록 설정을 할 수 있게 합니다.
이렇게 하는 이유로는 클래스내부에 작성된 메서드의 값을 직접적으로 접근하는 것을 피하고 메서드로 접근을 할 수 있도록 유도하는 것이며, 이를 통해 캡슐화를 할 수 있습니다.
그러면 우리는 메서드의 체력을 _health로 할 필요 없이 다른 것으로 작성을 해도 된다는 것
그러나 @property를 사용하게 된다면 AttributeError: property 'health' of 'Character' object has no setter
이런 오류를 만나게 될 텐데 이것은 읽기전용 속성을 제공하기 때문에 setter라는 것을 설정해 주어야 합니다.
그렇기 때문에 코드에서도 해당 코드를 입력하며 health의 값을 정의해 주어서 수정을 할 수 있도록 하는 기능을 넣어줍니다.
@health.setter
def health(self, value):
# 유효성 검사 등 추가 가능
if value < 0:
self._health = 0
else:
self._health = value
또한 __str__의 기능으로는 해당 인스턴스가 str로 사용이 될 때에 자동적으로 나오게 되는 결과를 표시해주는 기능인데 아래와 값이 user를 print하게 된다면 자동적으로 결과 값이 만들어져서 나오는 것을 확인 할 수 있습니다.
def __str__(self):
return f"Character(Health: {self._health}, Armor: {self.armor})"
print(user) # Character(Health: 90, Armor: 10)
객체지향 프로그래밍은 코드 재사용성, 유지보수 용이성, 캡슐화, 다형성 등의 장점을 통해 소프트웨어 개발의 효율성을 높이고, 복잡한 시스템을 더 쉽게 관리할 수 있도록 돕습니다. 이로 인해 OOP는 현대 소프트웨어 개발에서 필수적인 패러다임으로 자리잡고 있습니다.
대규모 프로젝트가 될수록 객체지향 프로그래밍을 사용해야하는 이유입니다.
'코딩 정리함' 카테고리의 다른 글
React 란?? (1) | 2024.10.02 |
---|---|
Oauth 2.0란? & JWT 토큰의 사용? (1) | 2024.09.27 |
예상 질문 답변 준비 (0) | 2024.08.29 |
면접 질문 대비 + CS 공부 (0) | 2024.08.27 |
면접 대비 질문 (0) | 2024.08.26 |