저번 시간에는 Python으로 객체 지향 프로그래밍을 할 때 알아야 할 것들을 함께 살펴봤습니다. 이번 시간에는 객체 지향 프로그래밍을 연습해보고 체화하는 시간을 가져보겠습니다.
스따박스 매장에서 고객들이 배달 주문을 할 수 있도록 전용 어플에 커피 메뉴를 게시하려 합니다. CoffeeMenu 클래스가 가져야 할 조건은 다음과 같습니다.
- 인스턴스 변수(자료형)
- name(문자열): 메뉴 이름
- price(정수): 메뉴 가격
- 인스턴스 메소드
- __init__: CoffeeMenu 클래스의 모든 인스턴스 변수를 초기화
- __str__: CoffeeMenu 인스턴스의 정보를 문자열로 반환. 단, 반환 형식은 정수
먼저, 클래스를 선언합니다.
class CoffeeMenu:
인스턴스 초기화를 위해 이닛 메소드를 선언합니다.
def __init__(self, name, price):
self.name = name
self.price = price
인스턴스 정보를 문자열로 반환하기 위해 던더 str 메소드를 선언합니다.
def __str__(self):
return f"{self.name} 가격: {self.price}"
메뉴 인스턴스를 생성합니다.
caramel = CoffeeMenu("카라멜 마끼야또", 3500)
chocolate = CoffeeMenu("초코라떼", 3000)
americano = CoffeeMenu("아메리카노", 1500)
메뉴 인스턴스를 출력합니다.
print(caramel)
print(chocolate)
print(americano)
카라멜 마끼야또 가격: 3500
초코라떼 가격: 3000
아메리카노 가격: 1500
계산기 클래스를 만들어보겠습니다. 객체 중에는 속성 없이 행동만 있는 객체도 있다고 했었죠? 이 말은 곧, 변수는 없고 메소드만 있는 클래스가 존재한다는 뜻입니다. 이러한 클래스에서 다루는 메소드가 바로 정적 메소드였습니다.
다음 조건들에 따라 계산기 클래스인 My_Calculator의 정적 메소드를 완성해보겠습니다.
- 정적 메소드
- add: 두 파라미터의 합
- subtract: 첫번째 파라미터 빼기 두번째 파라미터
- multiply: 두 파라미터의 곱
- divide: 첫번째 파라미터 나누기 두 번재 파라미터
클래스를 선언합니다.
class MyCalculator:
각각의 메소드를 선언합니다. 정적 메소드는 데코레이터를 활용합니다.
@staticmethod
def add(first_num, second_num):
return first_num + second_num
@staticmethod
def subtract(first_num, second_num):
return first_num - second_num
@staticmethod
def multiply(first_num, second_num):
return first_num * second_num
@staticmethod
def divide(first_num, second_num):
return first_num / second_num
인스턴스를 생성합니다.
calculator = MyCalculator()
계산기 연산을 호출하여 출력합니다.
print(calculator.add(3, 6))
print(calculator.subtract(3, 6))
print(calculator.multiply(3, 6))
print(calculator.divide(3, 6))
9
-3
18
0.5
게임 회사 레드홀에서 새로운 게임을 출시하려 합니다. 우리가 해야 할 일은 게임 캐릭터를 클래스로 작성하는 것인데요. 이 클래스의 이름은 GameCharacter입니다. 객체의 속성과 행동은 다음과 같습니다.
- 인스턴스 변수(자료형)
- name(문자열): 캐릭터 이름
- hp(숫자형): 캐릭터의 체력
- power(숫자형): 캐릭터의 공격력
- 인스턴스 메소드
- __init__: 사용할 모든 인스턴스 변수 초기화
- is_alive: 게임 캐릭터의 체력이 0보다 큰지(살았는지 죽었는지) 확인
--> 0 초과이면 True, 0 이하이면 False 반환- get_attacked: 게임 캐릭터의 체력이 0보다 큰 상태이면 파라미터로 받은 공격력만큼 체력 감소
--> is_alive 메소드를 사용해서 인스턴스가 살아있을 때만 체력 감소. 이미 캐릭터가 죽었다면 죽었다는 메세지 출력
--> 남은 체력보다 공격력이 더 크면 체력을 0으로 설정- attack: 파라미터로 받은 다른 캐릭터의 체력을 자신의 공격력만큼 깎음
--> is_alive 메소드를 이용해서 살아있는 인스턴스만 공격하게끔 할 것
--> get_attacked 메소드 사용- __str__: 게임 캐릭터의 의미있는 정보를 포함한 문자열 반환
클래스를 선언합니다.
class GameCharacter:
이닛 메소드를 선언합니다.
def __init__(self, name, hp, power):
self.name = name
self.hp = hp
self.power = power
게임 캐릭터가 살아있는지(체력이 0보다 높은지) 확인하는 메소드를 선언합니다. 0보다 높으면 True를, 0이하이면 False를 반환합니다.
def is_alive(self):
return self.hp > 0
게임 캐릭터가 살아있으면 공격한 캐릭터의 공격력만큼 체력을 깎는 메소드를 선언합니다.
def get_attacked(self, damage):
if self.is_alive():
self.hp = self.hp - damage if self.hp >= damage else 0
else:
print(f"{self.name}은 이미 죽었습니다.")
조건에 따라 get_attacked 메소드를 is_alive 메소드를 통해 구현하려면 인스턴스 이름.메소드 이름
구문을 사용하면 됩니다. is_alive가 True를 리턴하고 체력이 공격력보다 높으면 체력을 파라미터로 받은 damage만큼 빼고 체력이 공격력보다 낮으면 체력을 0으로 설정합니다. is_alive가 False를 리턴하면 이미 죽었다는 메세지를 출력해줍니다.
게임 캐릭터가 살아있으면 파라미터로 받은 다른 캐릭터의 체력을 자신의 공격력만큼 깎아주는 메소드를 선언합니다.
def attack(self, other_character):
if self.is_alive():
other_character.get_attacked(self.power)
이 메소드는 다른 캐릭터를 파라미터로 받습니다. 캐릭터가 살아있어야 공격이 가능하기 때문에 다시 한번 is_alive 메소드로 생존 여부를 확인해야 합니다.
other_character의 체력을 깎아야 하기 때문에 other_character 뒤에 get_attacked 메소드를 사용합니다. 이때, 파라미터로는 게임 캐릭터의 공격력을 넘겨줍니다.
마지막으로 게임 캐릭터의 의미 있는 정보를 포함한 문자열을 반환해주는 메소드를 선언합니다.
def __str__(self):
return f"{self.name}님의 hp는 {self.hp}만큼 남았습니다."
게임 캐릭터의 인스턴스를 생성합니다.
character1 = GameCharacter("타키탸키26", 100, 50)
character2 = GameCharacter("파이리12", 500, 70)
다음으로 게임 캐릭터 인스턴스들이 서로 공격하도록 합니다.
character1.attack(character2)
character2.attack(character1)
character2.attack(character1)
character2.attack(character1)
게임 캐릭터 인스턴스를 출력합니다.
print(character1)
print(character2)
타키탸키26님은 이미 죽었습니다.
타키탸키26님의 hp는 0만큼 남았습니다.
파이리12님의 hp는 450만큼 남았습니다.
이번에는 간단한 블로그 형식을 만들어보려고 합니다. 먼저, 게시글을 나타내는 Post 클래스를 정의해볼까요?
클래스를 선언합니다.
class Post:
이닛 메소드를 선언합니다.
def __init__(self, date, content):
self.date = date
self.content = content
게시글의 정보를 문자열로 리턴하는 던더 str 메소드를 선언합니다.
def __str__(self):
return f"게시일: {self.date}\n내용: {self.content}"
이제 블로그 유저를 나타내는 클래스 BlogUser를 정의해봅시다. 조건은 다음과 같습니다.
- 인스턴스 변수(자료형)
- name(문자열): 블로그 사용자의 이름
- posts(리스트): 블로그 게시글을 담을 리스트
- 인스턴스 메소드
- __init__: 인스턴스 변수가 설정되는 메소드
- add_post: 블로그 사용자의 블로그 게시글 리스트에 새로운 게시글 인스턴스를 추가하는 메소드
- show_all_posts: 블로그 사용자가 올린 모든 게시글을 출력하는 메소드
- __str__: 블로그 사용자의 간단한 인사와 이름을 문자열로 리턴하는 메소드
클래스를 선언합니다.
class BlogUser:
이닛 메소드를 선언합니다.
def __init__(self, name):
self.name = name
self.posts = []
BlogUser는 속성으로 이름과 게시글을 갖습니다. posts는 빈 배열로 초기화합니다.
새로운 게시글을 추가하는 add_post 메소드를 선언합니다. 이 메소드는 파라미터로 Post 클래스의 date와 content를 받습니다.
def add_post(self, date, content):
new_post = Post(date, content)
self.posts.append(new_post)
Post의 두 변수를 사용하기 위해 new_post를 선언했습니다. 이제 BlogUser의 posts 리스트에 new_post를 추가하면 됩니다.
블로그 유저의 모든 게시글을 출력하는 메소드를 선언합니다.
def show_all_posts(self):
for post in self.posts:
print(post)
반복문을 사용하여 posts 리스트에 있는 포스트들을 하나씩 출력합니다.
간단한 인사와 이름을 문자열로 리턴하는 던더 str 메소드를 선언합니다.
def __str__(self):
return f"안녕하세요 {self.name}입니다.\n"
블로그 유저 인스턴스를 생성합니다.
blog_user1 = BlogUser("타키탸키")
블로그 유저 인스턴스를 출력합니다.
print(blog_user1)
블로그 유저 게시글을 2개 추가합니다.
blog_user1.add_post("2021년 3월 6일", """
오늘은 내 생일이다.
너무 행복하다.
""")
blog_user1.add_post("2021년 3월 22일", """
오늘은 객체 지향 프로그래밍을 배웠다.
참 재밌었다.
""")
블로그 유저의 모든 게시글을 출력합니다.
blog_user1.show_all_posts()
안녕하세요 타키탸키입니다.
작성 날짜: 2021년 3월 6일
내용:
오늘을 내 생일이다.
너무 행복하다.
작성 날짜: 2021년 3월 22일
내용:
오늘은 객체 지향 프로그래밍을 배웠다.
참 재밌었다.
이번 시간에는 객체 지향 프로그래밍을 연습할 수 있는 간단한 문제들을 접해봤는데요. 여러 개념들이 등장했던 만큼 직접 코딩을 하며 익히는 것이 중요합니다.
다음 시간에는 조금 더 복잡한 객체 지향 프로그래밍을 해봅시다.
* 이 자료는 CODEIT의 '객체 지향 프로그래밍' 강의를 기반으로 작성되었습니다.