7. 클래스(class)
7.1 클래스의 개요
7.1.1 모듈(module) vs. 클래스(class) vs. 인스턴스(instance)
- 모듈 : .py로 끝나는 파일
- 클래스 : 새로운 자료형을 만드는 방법
- 인스턴스 : 클래스로부터 만들어낸 객체
7.1.2 클래스의 형식
class 클래스이름:
# Properties
nation = "한국"
name = str()
age = int()
# Methods
def display(self):
print('국적: ', self.nation, end=' ')
print(', 이름: ', self.nane, end=' ')
print(', 나이: ', self.age, end=' ')
7.1.3 클래스 내부의 method 선언 - def 키워드 사용
일반 함수와 다른 점은 첫번째 인수로 self 사용
self: 인스턴스 자신의 주소값을 가리킴
각 인스턴스들은 self를 이용하여 자신의 이름 공간에 접근
7.1.4 class method:
인스턴스와 무관하게 클래스 이름 공간에 존재하는 method
클래스 이름을 이용하여 호출함
첫 인수로 클래스 인스턴스를 자동으로 받는 method
7.1.5 __init__: 생성자(Constructor)
인스턴스가 생성될 때 자동으로 호출되는 method
self 인자가 정의되어야 함
7.1.6 __del__: 소멸자(Destructor)
인스턴스가 소멸 (메모리에서 해제)될 때 자동으로 호출되는 method
self 인자가 정의되어야 함
생략 가능(파이썬에서는 메모리나 기타 자원들을 자동으로 해제함)
7.1.7 상속(Inheritance)
코드의 재사용
자식 클래스는 상속을 해준 부모 클래스의 모든 기능을 그대로 사용
자식 클래스는 필요한 기능만을 정의하거나 기존의 기능을 변경할 수 있음
다중 상속 가능
7.1.8 오버라이드(Override)
서브 클래스에서 슈퍼 클래스에 정의된 method를 재정의하여 사용하는 기능
7.1.9 다형성(Polymorphism)
상속 관계 내의 다른 클래스들의 인스턴스들이 같은 멤버 함수 호출에 대해 각각 다르게 반응하도록 하는 기능
적은 코딩으로 다양한 인스턴스들에게 유사한 작업을 수행시킬 수 있음
코드의 가독성 향상
7.2 실습예제
class Person:
# Properties
nation = "한국"
name = str()
age = int()
height = float()
weight = float()
# Methods
# self: 인스턴스의 시작 번지값을 저장하는 변수(java의 this)
def display(self):
print('국적: ', self.nation, end=' ')
print(', 이름: ', self.name, end=' ')
print(', 나이: ', self.age, end=' ')
print(', 신장: ', self.height, end=' ')
print(', 체중: ', self.weight, end=' ')
# Person 클래스의 모든 인스턴스 확인
# dir(자료형)
print(dir(Person))
['__class__',
p1=Person()
p1.display() # 입력된 값이 없음
국적: 한국, 이름: , 나이: 0, 신장: 0.0, 체중: 0.0
p2=Person()
p2.name = '이도훈'
p2.age = 20
p2.height = 170.5
p2.weight = 60.5
p2.display()
국적: 한국, 이름: 이도훈, 나이: 20, 신장: 170.5, 체중: 60.5
# 인스턴스 변수(해당 인스턴스의 값만 바뀜)
p1.nation = 'China'
p1.display()
print()
p1.display()
국적: China, 이름: , 나이: 0, 신장: 0.0, 체중: 0.0
국적: 한국, 이름: 이도훈, 나이: 20, 신장: 170.5, 체중: 60.5
# 생성자와 소멸자
# 생성자 : __init__()
# 소멸자 : __del__()
class Person2:
# 생성자(중복 생성자는 허용되지 않음)
# 입력매개변수값이 없을 경우 None으로 작성
def __init__(self, name=None, age=None, height=None, weight=None):
self.name=name
self.age=age
self.height=height
self.weight=weight
# Method
def display(self):
print('이름: ', self.name, end=' ')
print(', 나이: ', self.age, end=' ')
print(', 신장: ', self.height, end=' ')
print(', 체중: ', self.weight, end=' ')
print()
# 입력매개변수에 전달되는 값이 없으므로 None이 할당된다.
p = Person2()
p.display()
p = Persion2()
p.name = '이도훈'
p.age = 20
p.height = 180.5
p.weight = 70.5
p.display()
p = Person2('이도훈', 20, 180.5, 70.5)
p.display()
이름: None, 나이: None, 신장: None, 체중: None
이름: 이도훈, 나이: 20, 신장: 180.5, 체중: 70.5
이름: 이도훈, 나이: 20, 신장: 180.5, 체중: 70.5
# 클래스 상속
# class 클래스명(상속할 클래스명)
class Calc2(Calculator)
def pow(self):
result = self.first ** self.second # 거듭제곱 연산자
return result
a = Calc2(2, 4);
# 상위클래스의 method 호출
print("sum: ", a.sum())
print("mul: ", a.mul())
print("sub: ", a.sub())
print("div: ", a.div())
# 하위클래스에서 추가한 method 호출
print("pow: ", a.pow())
# 상위클래스 Calculator에서 두번째 입력매개변수에 0을 입력하면 에러 발생
b = Calculator(4, 0)
# print("div: ", b.div())
# 분모에 0이 올 경우 0을 리턴하도록 코드 변경
class Calc3(Calculator):
# method override
def div(self):
if self.second == 0: # 나누는 값이 0인 경우 0을 리턴하도록 수정
# 파이썬에서는 다중상속이 가능하다.
# class 자식클래스(부모1, 부모2)
class Phone:
def call(self):
print('통화기능')
class Camera:
def picture(self):
print('촬영기능')
class CameraPhone(Phone, Camera):
def pictureCall(self):
print('영상통화기능')
p = CameraPhone()
p.call()
p.picture()
p.pictureCall()
# 데이터 은닉
# java와 같이 완벽한 캡슐화, 은닉화는 어렵다.
## __로 시작하는 변수는 외부에서 직접 값을 읽거나 바꿀 수 없다.
class BookReader:
__country = 'Korea'
def updateCountry(self, country):
self.__country = country
def getCountry(self):
return self.__country
# BookReader 클래스의 모든 인스턴스 확인
# __를 붙인 변수는 _클래스이름__변수로 이름이 바뀐다.
print(dir(BookReader))
br = BookReader()
print(br.getCountry())
# print(br.__country) # 에러 발생
# __로 시작하는 변수는 아래와 같이 사용할 수 있다.
print(BookReader._BookReader__country)
# __로 시작하는 변수는 값이 바뀌지 않는다.
br.__country = 'USA'
print(br.getCountry())
# method를 호출하여 수정할 경우는 변경이 가능하다.
br.updateCountry('China')
print(br.getCountry())