Object-Oriented Programming, OOP
클래스: 설계도
객체: 실생활에서 일종의 물건
의자라고 할 때
- 속성: 색, 다리의 개수, 다리의 모양 등
- 행동: 의자가 움직여지는 형태, 색이 바뀌는 것 등 수동적인 행동들
축구 팀이라고 할 때
- 속성: 선수 - 선수 이름, 포지션, 소속팀
팀 - 팀 이름, 팀 연고지, 팀소속 선수- 행동: 선수 - 공을 차다, 패스하다
심판 - 휘슬을 불다, 경고를 주다
클래스와 객체에 대해 많이 이야기한다
ex) 붕어빵 틀과 만들어지는 붕어빵
축구 선수 정보를 class로 구현하기
-class 선언 형태
init
을 사용📍 설계도 부분
class SocerPlayer(object):
def __init__ (self, name : str, position : str, back_number : int):
self.name = name
self.position = position
self.back_number = back_number
def __str__(self):
return "Hello, My name is %s. I play in %s in center " % \
(self.name, self.position)
def __add__(self, other):
return self.name + other
def change_back_number(self, new_number):
print('선수의 등번호를 변경합니다 : From %d to %d' % \
(self.back_number, new_number))
self.back_number = new_number
📍 설계도를 바탕으로 만들어내는 객체
abc = SocerPlayer('son', 'FW', 7)
park = SocerPlayer('park', 'WF', 13)
son.change_back_number(10)
~~>
선수의 등번호를 변경합니다 : From 7 to 10
print(son)
~~>
Hello. My name is son. My back number is 10
Note를 정리하는 프로그램
class Note(object):
def __init__(self, content = None):
self.content = content
def write_content(self, content):
self.content = content
def remove_all(self):
self.content = ""
def __add__(self, other):
return self.content + other.content
def __str__(self):
return self.content
class NoteBook(object):
def __init__(self, title):
self.title = title
self.page_number = 1
self.notes = {}
def add_note(self, note, page = 0):
if self.page_number < 300:
if page == 0:
self.notes[self.page_number] = note
self.page_number += 1
else:
self.notes = {page : note}
self.page_number += 1
else:
print("Page가 모두 채워졌습니다.")
def remove_note(self, page_number):
if page_number in self.notes.keys():
return self.notes.pop(page_number)
else:
print("해당 페이지는 존재하지 않습니다")
def get_number_of_pages(self):
return len(self.notes.keys())
📍 불러와서 사용하기
from teamlab_note import Note
from teamlab_note import NoteBook
✨ Inheritance( 상속 )
class Person(object): # 부모 클래스 Person 선언
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def about_me(self): # Method 선언
print("저의 이름은 ", self.name, "이구요, 제 나이는 ", str(self.age), "살입니다.")
myPerson = Person('John', 23, 'Male')
myPerson.about_me()
~~>
저의 이름은 John 입니다. 나이는 23 살이고 Male 입니다.
📍 super를 통해 부모클래스에 있는 정보를 가져와 사용
class Employee(Person): # 부모 클래스 Person으로 부터 상속
def __init__(self, name, age, gender, salary, hire_date):
super().__init__(name, age, gender) # 부모객체 사용
self.salary = salary
self.hire_date = hire_date # 속성값 추가
def do_work(self): # 새로운 메서드 추가
print("열심히 일을 합니다.")
def about_me(self): # 부모 클래스 함수 재정의
super().about_me() # 부모 클래스 함수 사용
print("제 급여는 ", self.salary, "원 이구요, 제 입사일은 ", self.hire_date,
" 입니다.")
myEmpolyee = Employee('Daeho', 34, 'Male', 300000, '2012/12/12')
myEmpolyee.about_me()
~~>
저의 이름은 Daeho 입니다. 나이는 34 살이고 Male 입니다.
제 급여는 300000 원 이구요, 제 입사일은 2012/12/12 입니다.
✨ Polymorphism( 다형성 )
class Animal:
def __init__(self, name): # Constructor of the class
self.name = name
def talk(self): # Abstract method, defined by convention only
raise NotImplementedError("Subclass must implement abstract method")
class Cat(Animal):
def talk(self):
return 'Meow!'
class Dog(Animal):
def talk(self):
return 'Woof! Woof!'
animals = [Cat('Missy'),
Cat('Mr. Mistoffelees'),
Dog('Lassie')]
for animal in animals:
print(animal.name + ': ' + animal.talk())
~~>
Missy:Meow!
Yeorem:Woof!
✨ Visibility( 가시성 )
객체의 정보를 볼 수 있는 레벨을 조절하는 것
누구나 객체 안에 모든 변수를 볼 필요가 없음
- 객체를 사용하는 사용자가 임의로 정보수정
- 필요 없는 정보에는 접근 할 필요가 없음
- 만약 제품으로 판매한다면? 소스의 보호
캡슐화 또는 정보 은닉( Information Hiding)
Class를 설계할 때 클래스 간 간섭 / 정보공유의 최소화
📍 Example 1
class Product(object):
pass
class Inventory(object):
def __init__(self):
self.__items = [] # Private 변수로 선언 -> 타객체가 접근 못함
def add_new_item(self, product):
if type(product) == Product:
self.__items.append(product)
print("new item added")
else:
raise ValueError("Invalid Item")
def get_number_of_items(self):
return len(self.__items)
my_inventory = Inventory()
my_inventory.add_new_item(Product())
my_inventory.add_new_item(Product())
my_inventory
~~>
new item added
new iten added
<__main__.Inventory at 0x------------->
my_inventory.items.append('abc')
my_inventory.items
~~>
[<__main__.Inventory at 0x------------->
<__main__.Inventory at 0x------------->
'abc',
'abc']
📍 Example 2
class Inventory(object):
def __init__(self):
self.__items = []
@property # property decorator 숨겨진 변수를 반환하게 해줌
def items(self):
return self.__items
my_inventory = Inventory()
my_inventory.add_new_item(Product())
my_inventory.add_new_item(Product())
print(my_inventory.get_number_of_items())
~~>
new item added
new item added
# 접근이 불가능하기 때문에 error가 발생한다
items = my_inventory.items
items.append(Product())
print(my_inventory.get_number_of_items())
~~>
<__main__.Inventory at 0x------------->
First-class Object