OOP
OOP
- 객체(Object)
- 객체지향프로그래밍(Object Oriented Programming)
- 클래스(Class)와 객체(Object)
1. 객체
Python에서 모든 것은 객체(object)이다. 모든 객체는 타입(type), 속성(attribute), 조작법(method)을 가진다.
type | instance |
---|---|
int | 0, 1, 2 |
str | '', 'hello', '123' |
list | [], ['a', 'b'] |
dict | {}, {'key': 'value'} |
- 타입 : 공통된 속성(attribute)과 조작법(method)을 가진 객체들의 분류
- 인스턴스 : 특정 타입(type)의 실제 데이터 예시(instance)이다.
type | attributes | methods |
---|---|---|
complex | .real, .imag | |
str | _ | .capitalize(), .join(), .split() |
list | _ | .append(), .reverse(), .sort() |
dict | _ | .keys(), .values(), .items() |
# 객체.속성 형식으로 사용
complex_number.real
# 객체.매서드 형식으로 사용
complex_number.imagmy_list.sort()
1.1 매서드
- 특정 객체에 적용할 수 있는 행위(behavior)를 뜻 한다.
dir()
로 해당 타입의 객체들의 매서드 확인 가능
2. 객체 지향 프로그래밍(Object-Oriented Programming)
Object가 중심(oriented)이 되는 프로그래밍
객체지향의 장점
- 코드의 직관성
- 활용의 용이성
- 변경의 유연성
3. 클래스(Class)와 객체(Object)
type
: 공통 속성을 가진 객체들의 분류(class)class
: 객체들의 분류(class)를 정의할 때 쓰이는 키워드
3.1 클래스(Class) 생성
- 클래스 생성은
class
키워드와 정의하고자 하는<클래스의 이름>
으로 가능하다. <클래스의 이름>
은PascalCase
로 정의한다.- 클래스 내부에는 데이터와 함수를 정의할 수 있고, 이때 데이터는 속성(attribute) 정의된 함수는 메서드(method)로 불린다.
class Person:
# _ underscore
def __init__(self, name): # 속성에 대한 정보를 저장
self.name = name
def talk(self):
return f'안녕, 나는 {self.name}'
john = Person('john')john.talk()
self
: 인스턴스 자신- Python에서 인스턴스 메서드는 호출 시 첫번째 인자로 인스턴스 자신이 전달되게 설계되었다.
- 보통 매개변수명으로
self
를 첫번째 인자로 설정 (다른 이름도 가능하지만 추천하지는 않는다.)
생성자와 소멸자
- 생성자 : 인스턴스 생성시 호출되는 함수
def __init__(self):
- 소멸자 : 인스턴스가 소멸되기 직전에 호출되는 함수
def __del__(self):
- 생성자 : 인스턴스 생성시 호출되는 함수
속성 정의
class Person: def __init__(self, name): self.name = name def talk(self): print(f'안녕, 나는 {self.name}') # 속성에 접근하여 클래스 밖에서도 직접 변경 가능junsung.talk() junsung = Person('junsung') junsung.talk()junsung.name = '준성'
매직메서드
# 특정 객체를 출력(print()) 할 때 보여줄 내용을 정의할 수 있음 ['__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__'] class Person: def __str__(self): return '객체 출력(print)시 보여줄 내용'
4. 인스턴스 & 클래스 변수
4.1 인스턴스 변수
- 인스턴스의 속성(attribute)
- 각 인스턴스들의 고유한 변수
- 메서드 정의에서
self.변수명
로 정의 - 인스턴스가 생성된 이후
인스턴스.변수명
로 접근 및 할당
class Person:
def __init__(self, name):
#인스턴스 매서드중에 특별한 생성자 매서드..
self.name = name
park = Person('park')
lee = Person('lee')
print(park.name)
print(lee.name)
4.2 클래스 변수
- 클래스의 속성(attribute)
- 모든 인스턴스가 공유
- 클래스 선언 내부에서 정의
클래스.변수명
으로 접근 및 할당
# 클래스 내에 변수 지정 가능 => 클래스 변수
class Person:
species = '사람'
# 클래스에 넣어놓은 변수는 바뀌지 않음
Person.speciesiu = Person()
iu.speciesiu.species = '신'
iu.speciesPerson.species
4.3 인스턴스 & 클래스간의 이름공간
- 클래스를 정의하면, 클래스가 생성됨과 동시에 이름 공간(namespace)이 생성된다.
- 인스턴스를 만들게 되면, 인스턴스 객체가 생성되고 해당되는 이름 공간이 생성된다.
- 인스턴스의 어트리뷰트가 변경되면, 변경된 데이터를 인스턴스 객체 이름 공간에 저장한다.
- 즉, 인스턴스에서 특정한 어트리뷰트에 접근하게 되면 인스턴스 => 클래스 순으로 탐색을 한다.
5. 메서드의 종류
5.1 인스턴스 메서드(instance method)
- 인스턴스가 사용할 메서드
- 클래스 내부에 정의되는 메서드의 기본값은 인스턴스 메서드
- 호출시, 첫번째 인자로 인스턴스 자기자신
self
이 전달됨
class MyClass:
def instance_method(self, arg1, arg2, ...):
...
5.2 클래스 메서드(class method)
- 클래스가 사용할 메서드
@classmethod
데코레이터를 사용하여 정의- 호출시, 첫 번째 인자로 클래스
cls
가 전달됨
class MyClass:
@classmethod
def class_method(cls, arg1, arg2, ...):
5.3 스태틱 메서드(static method)
- 클래스가 사용할 메서드
@staticmethod
데코레이터를 사용하여 정의- 호출시, 어떠한 인자도 전달되지 않음
class MyClass:
@staticmethod
def static_method(arg1, arg2, ...):
5.4 비교정리
- 인스턴스는 3가지 메서드 모두에 접근 가능
- 하지만 인스턴스에서 클래스 메서드와 스태틱 메서드는 호출하지 않아야 한다. (가능하다 != 사용한다)
- 인스턴스가 할 행동은 모두 인스턴스 메서드로 한정 지어서 설계한다.
클래스 또한 3가지 메서드 모두에 접근할 수 있다.
하지만 클래스에서 인스턴스 메서드는 호출하지 않는다. (가능하다 != 사용한다)
클래스가 할 행동은 다음 원칙에 따라 설계한다. (클래스 메서드와 정적 메서드)
클래스 자체(
cls
)와 그 속성에 접근할 필요가 있다면 클래스 메서드로 정의한다.클래스와 클래스 속성에 접근할 필요가 없다면 정적 메서드로 정의한다.
- 정적 메서드는
cls
,self
와 같이 묵시적인 첫번째 인자를 받지 않기 때문
- 정적 메서드는
6. 상속
6.1 상속
- 클래스에서 가장 큰 특징은
상속
이 가능하다는 것이다. - 부모 클래스의 모든 속성이 자식 클래스에게 상속 되므로 코드 재사용성이 높아진다.
class Person:
population = 0
def __init__(self, name='사람'):
self.name = name
Person.population += 1
def talk(self):
print(f'반갑습니다. {self.name}입니다.')
class Student(Person):
def __init__(self, name, student_id):
# 초기값은 부모클래스의 초기값을 덮어쓰워짐
self.name = name
self.student_id = student_id
- 상속 검사
# 전자가 후자의 서브클래스인가? True
issubclass(Student, Person)
# 인스턴스인가? True
isinstance(s1, Student)
# 인스턴스인가? True
isinstance(s1, Person)
# 타입이 같은가? False (타입에 대해서 상속은 이뤄지지 않음)
type(s1) is Person
#bool은 int의 자식클래스이기에 인스턴스 여부는 True
isinstance(True, int)
# 타입은 같이 않으므로 False
type(True) is int
# 서브클래스는 True
issubclass(bool, int)
# 이 메서드로 해당 클래스의 상속관계 확인 가능
bool.mro()
6.2 super()
- 자식 클래스에 메서드를 추가로 구현할 수 있다.
- 부모 클래스의 내용을 사용하고자 할 때,
super()
를 사용할 수 있다.
class Person:
population = 0
def __init__(self, name):
self.name = name
Person.population += 1
def talk(self):
print(f'반갑습니다. {self.name}입니다.')
class Student(Person):
def __init__(self, name, student_id):
super().__init__(name) # 부모 클래스의 내용을 그대로 상속
self.student_id = student_id # 추가적으로 필요한 내용만 작성
6.3 다중상속
class Person:
def __init__(self, name):
self.name = name
def talk(self):
print('사람입니다')
class Mom(Person):
gene = 'XX'
def swim(self):
print('첨벙첨범')
class Dad(Person):
gene = 'XY'
def walk(self):
print('씩씩하게 걷기')
# 부모클래스에서 동일한 클래스변수가 있을때는 먼저 상속한 클래스에서 가져옴
class FirstChild(Mom, Dad):
def __init__(self):
def cry(self):
print('응애')
def walk(self):
print('아장아장')
7. 메서드 오버라이딩
Method Overriding(메서드 재정의): 자식 클래스에서 부모 클래스의 메서드를 재정의하는 것
- 상속 받은 메서드를
재정의
할 수도 있다. - 상속 받은 클래스에서 같은 이름의 메서드로 덮어쓴다.
class Person:
def __init__(self, name, age, number, email):
self.name = name
self.age = age
self.number = number
self.email = email
def talk(self):
print(f'안녕, {self.name}')
class Soldier(Person):
def __init__(self, name, age, number, email, level):
super().__init__(name, age, number, email)
self.level = level
def talk(self):=
# 동일한 이름의 메서드를 자식클래스에서도 선언하는 경우 덮어씀
if self.level == '참모총장':
print('내 밑으로 집합')
else:
print(f'충성 충성 {self.level}, {self.name}입니다 ^^7')
'Python' 카테고리의 다른 글
Python_06_모듈&패키지 (0) | 2021.04.09 |
---|---|
Python_05_데이터_구조 (0) | 2021.04.07 |
Python_04_예외처리 (0) | 2021.04.06 |
Python_03_함수 (0) | 2021.04.05 |
Python_02_제어문 (0) | 2021.04.04 |