객체지향 프로그래밍의 이해
*모든 출처는 아이티윌 이광호 강사님
<학습 목표>
-클래스와 객체
-self와 생성자
-정보은닉
-클래스 상속
클래스와 객체
객체는 기본적으로 필요에 따라 다른 변수와 함수를 내장하고 있는 특수한 변수
-명사적 특성과 동사적 특성이 있음
-객체를 구성하는 것은 데이터와 기능으로,
데이터는 멤버 변수 같은 변수로, 기능은 메서드 함수로 표현된다
-객체는 설계도 역할을 하는 프로그램 소스로, 하나의 클래스로 같은 구조를 가지는 객체를 여러개 생성할 수 있다
ex) 메이플 게임에서 버섯 몹이 있으면, 모두 하나의 클래스에서 만들어졌고,
각 몹들의 특성 변화는 모두 독립적 (공격 받으면 공격 받은 버섯의 hp 만 줄어드는 것처럼)
-class 에 속하는 모든 매서드는 첫 파라미터로 self 값 명시 필요
-객체에 부여된 기능에 접근하는 유형은 세가지
print(객체.멤버변수)
변수 =객체.멤버변수
객체.(메서드)
(클래스는 직접 작동을 못하고 객체에 부여되었을 때 작동하는 개념)
일반적으로는 처음에 클래스 생성시 멤버변수는 None 으로 설정하고 이후에 값을 할당하여 사용
SELF 와 생성자
-객체가 자기 자신을 가르키는 키워드로
-'우리 집' '우리 아빠' 처럼 같은 클래스에서 서로 호풀할 떄는 SELF 를 통해서 접근해야함
-SELF 는 전역 변수의 역할도 하면서 클래서 안의 모든 매서드가 공유할 수 있다
생성자
-객체가 생성될 때 자동으로 실행되는 매서드
-값을 리턴하는 것은 아니고, 생성자의 이름은 __inti__ 으로 (언더바 두번씩) 약속되어 있음
-각 객체와 멤버변수를 하나씩 설정해주는 것 보다, 생성자를 통해서 객체를 생성하는게 코드의 효율성을 높힐 수 있음
예시
class monster:
hp:None
monster_power:None
#객체의 속성을 일괄 출력하는 메서드
def state(self):
print("현재 체력은 {0}, 공격력은 {1}".format(self.hp,self.monster_power))
#레벨업 -> 모든 속성 멤버 변수들이 증가한다
def level_up(self):
self.hp += 10
self.monster_power +=2
print("몬스터가 레벨업 하면서 체력은 +10 , 공격력은 +2 올라갔습니다")
#공격을 받아 hp 가 감소합니다
def attacked(self,attack):
self.hp -=attack
print('공격을 받아 hp 가 {0} 으로 감소합니다'.format(self.hp))
mushroom=monster()
mushroom.hp=100
mushroom.monster_power =20
mushroom.state()
mushroom.level_up()
mushroom.attacked(30)
>>
현재 체력은 100, 공격력은 20
몬스터가 레벨업 하면서 체력은 +10 , 공격력은 +2 올라갔습니다
공격을 받아 hp 가 80 으로 감소합니다
예시2
class Marine:
name = None
hp = None
# 생성자 — 객체가 만들어질 때 자동 실행
def __init__(self, name, hp):
self.name = name
self.hp = hp
print("[{0}] You wanna piece of me, boy?".format(self.name))
# 객체의 상태 출력
def state(self):
print("[{0}] hp: {1}".format(self.name, self.hp))
# 레벨업 메서드
def level_up(self):
self.hp += 5
print("[{0}] 레벨업을 하여 체력이 (+5) 증가했습니다.".format(self.name))
# 공격받을 때 HP 감소
def attacked(self, enemy_attack):
self.hp -= enemy_attack
print("[{0}] 적의 공격을 받아 hp가 {1} 감소했습니다.".format(self.name, enemy_attack))
m1 = Marine("마린1", 100)
m2 = Marine("마린2", 100)
m1.state()
m2.state()
m1.attacked(30)
m2.attacked(20)
m1.state()
m2.state()
m1.level_up()
m2.level_up()
m1.state()
m2.state()
정보 은닉 (캡슐화)
getter 와 setter 는 한쌍으로 존재
이걸 간단하게 표현하는게 프로퍼티
*getteㄱ 가 setter 보다 더 먼저 정의
직접 초기화하는게아니라 setter 를 호출한다
함수 호출이 아니라
self.name 이 변수가 아니라 앞에 나온 매서드들을 통해서 값을 리턴받는 것
값 하나가 두개를 다 호출하는 경우
클래스 상속
class Terran:
name=None
hp=None
def __init__(self,name,hp):
self.name=name
self.hp=hp
def info(self):
return "[%s] HP: %d"%(self.name,self.hp)
class Marine(Terran): #Marine 은 Terran 을 상속받아 위에 존재하는 생성자와 변수들을 그대로 상속받는다
def shoot(self,attack): #기존 Terra 에는 존재하지 않던 새로운 매서드를 정의하여 기능을 확장한다
return "[%s] 총을 쏘아 %d의 데미지를 입혔습니다" %(self.name,attack)
m=Marine('마린1',45)
print(m.info())
print(m.shoot(100))
super() 를 사용한 부모 기능호출하기
class Medic(Terran):
mana=None
def __init__(self,name,hp,mana):
super().__init__(name,hp)
self.mana=mana
def info_ex(self):
info_msg=super().info()
info_msg += ", MANA :%d" %self.mana
return info_msg
def heel(self,target):
self.mana-+5
return "[%s] %s의 체력을 회복시킵니다 (mana:-5)"%(self.name,target)
md=Medic('메딕1',30,100)
print(md.info_ex())
print(md.heel('마린1'))
<오류 발생했던 코드>
class Medic(Terran):
mana=None
def __init__(self,name,hp,mana):
super().__init__(name,hp)
self.mana=mana
def info_ex(self):
info_msg=super().info
info_msg += ", MANA :%d" %self.mana
return info_msg
def heel(self,target):
self.mana-+5
return "[%s] %s의 체력을 회복시킵니다 (mana:-5)"%(self.name,target)
md=Medic('메딕1',30,100)
print(md.info_ex())
print(md.heel('마린1'))
이 부분에서 info 를 호출하지 않아 아래와 같은 오류가 발생했음
TypeError: unsupported operand type(s) for +=: 'method' and 'str'
오류 메세지의 의미는 문자열을 더하려고 했는데 왼쪽이 함수 (매서드)였다 라는 뜻
이는 info 메서드를 호출하지 않고 그대로 대입해서 발생한 오류
super().info 는 함수 객체이고
super().info() 는 함수를 실행한 결과가 문자열임
파이썬에서는 () 가 있으면 호출되어서 실행 결과값을 의미하고
없으면 객체(매서드) 자체를 가리키는 참조
예를들어서 아래처럼 greet 자체는 객체이지만 greet() 은 실행 후의 결과값을 의미하게 된
def greet():
return "안녕"
greet # 함수 “객체”를 가리킴 (실행 X)
greet() # 함수를 “실행” → "안녕"
매서드에서도 () 유무에 따라서 결과 값을 실행하는지 안하는지가 나뉘게 된다
s = "abc"
s.upper # 메서드 객체 (실행 X)
s.upper() # "ABC"
자식 하위모드에서 새로 정의하면 상속받은 부모로부터의 값 말고도 더 활용할 수있따
오버라이드
#매서드 오버라이드 > 부모 클래스의 기능 수정하기
class Animal:
def sound(self):
print("동물이 소리를 냅니다.")
class Dog(Animal):
def sound(self): #부모로부터 상속받은 sound() 매서드를 수정할 수 있다
print("멍멍!")
a=Animal()
a.sound()
d=Dog()
d.sound()
==============================
#부모 클래스의 기능을 유지하면서 추가적인 기능을 덧붙이는 오버라이드
#부모의 매서드를 오버라이드하는 매서드 안에서는 super() 함수를 통해 재정의되기 전의 원본 기능에 접근할 수 있음
class Animal:
def sound(self):
print("동물이 소리를 냅니다")
class Cat(Animal):
def sound(self):
super().sound()
print('야옹')
c=Cat()
c.sound()
*불필요한 기능까지 상속받는 몬스터가 생김 (npc 와 대화, 아이템 줍기)
그래서 하나의 클래스에 너무 여러 기능을 넣기보다 각 기능들을 특징에 따라 카테고리화 해서 관리하고
이로인해 다중 상속이 필요함
'빅데이터 국비 교육' 카테고리의 다른 글
[아이티윌 빅데이터 52기] Day 11 Python Basic | 딕셔너리/예외처리/파일 입출력 (0) | 2025.10.21 |
---|---|
[아이티윌 빅데이터 52기] Day 10 Python Basic | 리스트의 탐색 (0) | 2025.10.20 |
[아이티윌 빅데이터 52기] Day 9 Python Basic | 프로그램 흐름 제어 / 리스트 (1) (0) | 2025.10.17 |
[아이티윌 빅데이터 52기] Day 8 Python Basic | 함수의 이해 / 코딩 테스트 준비 / 조건문과 반복문 (0) | 2025.10.16 |
[아이티윌 빅데이터 52기] Day 7 Python Basic (0) | 2025.10.15 |