KDT 수업/Python
[파이썬] 16. 객체지향과 클래스
니니는 진짜 전설이다
2023. 3. 10. 16:53
1. 객체지향 프로그래밍
- 문제를 여러개의 객체 단위로 나눠 작업하는 방식
1-1. 객체(Object)란?
- 물리적으로 존재하거나 추상적으로 생각할 수 있는 것 중에서 자신의 속성을 가지고 있고 다른것과 식별 가능한 것을 말함(in real life)
- 클래스에 정의된 내용대로 메모리에 생성된 것을 객체라고 함(in programming)
1-2. 클래스(class)란?
- 객체를 생성하기 위한 일종의 설계도와 같음
- 클래스는 프로퍼티(필드), 메소드(함수)로 구성되어있음
- 프로퍼티(Property): 데이터가 저장되는 곳
- 메소드(method): 객체의 동작에 해당하는 실행 블록
1-3. 클래스와 객체
- 건축 설계도가 클래스라면, 실제로 지어진 집은 객체
- 객체는 클래스로 생성되어 구체화된 인스턴스
- 실제로 클래스가 인스턴스화 되어 메모리에 상주하는 형태를 객체라고 부름
- 파이썬의 모든 변수와 함수는 객체로 저장
2. 클래스 만들기
```
class 클래스명:
프로퍼티명1 = 값1
프로퍼티명2 = 값2
...
def 메소드명(self, 변수1, 변수2, ...):
메소드가 호출되면 실행할 문장
...
def 메소드명2(self, 변수1, 변수2, ...):
메소드가 호출되면 실행할 문장
...
```
- 클래스를 통해 호출되는 변수를 프로퍼티(필드)라고 부름
- 클래스를 통해 호출되는 함수를 메소드라고 부름
- self: 클래스의 각 호출한 객체를 가리킴(어떤 곳에서 메소드를 호출하는지 알기 위해) (-> 셀프를 붙여야 다른 곳에서도 사용 가능)
- 클래스의 앞글자는 항상 대문자로 쓴다
class Dog:
pass #내용이 없는 블록을 만들 때 사용
def func1():
pass
# 클래스를 통해 객체를 생성
Rucy = Dog()
print(Rucy)
print(type(Rucy))
>>
<__main__.Dog object at 0x7fb09c33e700>
<class '__main__.Dog'>
PPomi = Dog()
print(PPomi)
print(type(PPomi))
>>
<__main__.Dog object at 0x7fb09c5ac160>
<class '__main__.Dog'>
>> 같은 클래스를 이용하지만 메모리 주소는 다름을 알 수 있다
class Dog:
name = '루시'
age = 13
family = '포메'
def eat(s):
print(s)
print('사료를 먹습니다!')
Rucy = Dog()
print(Rucy.name)
print(Rucy.age)
print(Rucy.family)
Rucy.eat()
print(Rucy)
>>
루시
13
포메
<__main__.Dog object at 0x7fb09c33ea60>
사료를 먹습니다!
<__main__.Dog object at 0x7fb09c33ea60>
PPomi = Dog()
print(PPomi.name)
print(PPomi.age)
print(PPomi.family)
PPomi.eat()
print(PPomi)
>>
루시
13
포메
<__main__.Dog object at 0x7fb09c33e9a0>
사료를 먹습니다!
<__main__.Dog object at 0x7fb09c33e9a0>
3.생성자(Constructor)
- 클래스를 객체화시킬 때 가장 먼저 실행되는 메소드
- __ init __(self)
- 생성자에서는 해당 클래스가 다루는 데이터를 정의하고 초기화 함
class Dog():
def __init__(self):
print(self, 'init 호출!')
Rucy = Dog()
>> <__main__.Dog object at 0x7fb09c33ec70> init 호출!
class Dog():
def __init__(self):
self.name = '이름없음'
self.age = 0
Rucy = Dog()
print(Rucy)
print(Rucy.name)
print(Rucy.age)
>>
<__main__.Dog object at 0x7fb08c8218b0>
이름없음
0
PPomi = Dog()
print(PPomi)
print(PPomi.name)
print(PPomi.age)
>>
<__main__.Dog object at 0x7fb09c33ed90>
이름없음
0
Rucy.name = '루시'
Rucy.age = 13
PPomi.name = '뽀미'
PPomi.age = 7
print(Rucy)
print(Rucy.name)
print(Rucy.age)
>>
<__main__.Dog object at 0x7fb08c8218b0>
루시
13
print(PPomi)
print(PPomi.name)
print(PPomi.age)
>>
<__main__.Dog object at 0x7fb09c33ed90>
뽀미
7
class Dog():
def __init__(self):
self.name = '이름없음'
self.age = 0
# nickname = '닉네임없음' #메소드 안에서만 사용할 수 있는 지역변수
self.nickname = '닉네임없음'
# print(f'{nickname} 객체가 생성됨')
# def go(self):
# print(f'{self.name}가 달립니다')
def go(self):
print(f'{self.nickname}가 달립니다')
Rucy = Dog()
Rucy.name = '루시'
Rucy.go()
>>닉네임없음가 달립니다
class Dog:
def __init__(self, name, age, nickname = 'no nickname'):
self.name = name
self.age = age
self.nickname = nickname
Rucy = Dog() # 매개변수를 보내지 않아 에러가 발생함
# TypeError: __init__() missing 2 required positional arguments: 'name' and 'age'
Rucy = Dog('루시', 13)
print(Rucy.name)
print(Rucy.age)
print(Rucy.nickname)
>>
루시
13
no nickname
PPomi = Dog('뽀미', 7)
print(PPomi.name)
print(PPomi.age)
print(PPomi.nickname)
>>
뽀미
7
no nickname
4. 메소드 정의하기
- 해당 클래스의 객체에서만 호출 가능한 함수를 메소드라고 한다
- 해당 객체의 속성에 대한 연산을 행함
- 객체이름.메소드명()형태로 호출됨
4-1. 메소드 정의하기
class Counter:
def __init__(self):
self.num = 0
def increment(self):
self.num += 1
def decrement(self):
self.num -= 1
def current_value(self):
return self.num
def reset(self):
self.num = 0
KBbank = Counter()
print(KBbank.num)
>> 0
KBbank.increment()
print(KBbank.num)
>> 1
KBbank.decrement()
print(KBbank.num)
>> 0
print(KBbank.current_value())
>> 0
KBbank.increment()
KBbank.increment()
KBbank.increment()
KBbank.increment()
KBbank.increment()
print(f'현재 대기인원: {KBbank.current_value()}')
>> 현재 대기인원: 5
HanaBank = Counter()
print(f'현재 대기인원: {HanaBank.current_value()}')
>> 현재 대기인원: 0
HanaBank.increment()
HanaBank.increment()
HanaBank.increment()
print(f'현재 대기인원: {HanaBank.current_value()}')
>> 현재 대기인원: 6
HanaBank.reset()
print(f'현재 대기인원: {HanaBank.current_value()}')
>> 현재 대기인원: 0
4-2. 메소드 타입
- instance method: 객체 형태로 호출되기 때문에 해당 메소드를 호출한 객체에만 영향을 미침
- class method: 클래스 이름으로 호출하는 메소드(메소드 선언 위에 @staticmethod라고 표기)
class Math:
def add(self, x, y):
return x + y
def multiply(self, x, y):
return x * y
math = Math()
result1 = math.add(10, 3)
print(result1)
>> 13
result2 = math.multiply(10, 3)
print(result2)
>> 30
class Math:
@staticmethod #staticmethod는 객체 생성 안해서 self 필요 없음. 그냥 바로 클래스를 통해 값을 받을 수 있다.
def add(x, y):
return x + y
@staticmethod
def multiply(x, y):
return x * y
result1 = Math.add(10, 3)
print(result1)
>> 13
result2 = Math.multiply(10, 3)
print(result2)
>> 30
class Math:
@staticmethod
def add(x, y):
return x + y
@staticmethod
def multiply(x, y):
return x * y
def div(self, x, y): #self -> 객체 생성해서 호출 해야함
return x/y
math = Math()
result3 = math.div(10, 3)
print(result3)
>> 3.3333333333333335