You are on page 1of 18

3 객체지향 프로그래밍 심화

목차 1 2

정보은닉 객체참조

3 4

클래스 변수 특수 메소드
정보 은닉
지금까지는 클래스 안의 인스턴스 변수나 메소드를
누구나 사용할 수 있었음

하지만 이렇게 하는 것이 좋은 것일까?

class Student: class Student:


def __init__(self, name=None, age=0) def __init__(self, name=None,
self.name=name birthday=“20000101”)
self.age=age self.name=name
self.birthday=birthday
obj=Student(“Yoon”,20)
obj.age=-10 obj=Student(“Yoon”,20)
print(obj.age) obj.age=20 #문제 발생!

-10
• 클래스 유지 보수를 위해
인스턴스 변수 변경 시
• 잘못된 외부 입력에 의해
기존의 클래스를 사용하던
• 인스턴스 변수의 값이 코드에서 문제 발생
올바르지 않게 변경
→ 결론:
무조건적인 공개는 옳지 않음
정보 은닉
정보 은닉이란?
• 구현의 세부 사항을 클래스 안에 감추는 것
• 클래스 안의 데이터를 외부에서 마음대로 변경하지 못하게 하는 것

• private 변수
• private변수의 제어는 클래스 내 메소드를 활용
→ 예상된 범위 내에서만 변경 가능

A클래스
인스턴스
메소드 변수들
정보 은닉
파이썬에서 인스턴스 변수를 private로 정의하려면
변수 이름 앞에 __을 붙이면 됨
• private 변수는 클래스 내부에서만 접근 가능
class Student:
def __init__(self, name=None, age=0):
self.__name = name # __가 변수 앞에 붙으면 외부에서 변경 금지
self.__age = age # __가 변수 앞에 붙으면 외부에서 변경 금지

obj=Student( )
print(obj.__age)

...
AttributeError: 'Student' object has no attribute '__age'
정보 은닉
접근자(getters)와 설정자(setters)
• private 변수의 값을 읽거나 변경하기 위해서는
이를 수행하는 내부 메소드 필요
class Student:
def __init__(self, name=None, age=0):
self.__name = name
self.__age = age

def getAge(self):
return self.__age

def getName(self):
return self.__name
- 일반적으로 get이나 set이
def setAge(self, age): 메소드 이름 앞에 붙여짐
self.__age=age - 더 불편한 건 아닌가?
def setName(self, name): 접근자에 의해 잘못된 값이
self.__name=name 넘어오는 경우
이를 사전 차단 가능
obj=Student("Hong", 20) (예: 음수 나이)
obj.getName( )

Hong
객체 참조
파이썬에서 변수는 실제로 객체를 저장하지 않는다
• 객체의 메모리 주소를 저장(참조) 하며,
객체 자체는 메모리의 다른 곳에 생성됨

생성자 Television( )은
새로운 객체에 대한 주소를
반환하고 이것을 t에 저장
객체 참조
참조의 공유
• 객체의 참조(주소)값을 저장하고 있는 변수를 다른 변수로 복사하면?
• 객체 자체가 복사되는 것이 아닌 참조(주소)값만이 복사

t = Television(11, 10, True)


s=t
s.channel = 9

s를 통해 객체 수정 시
t가 가리키는 객체의 값도 변경
객체 참조
is, is not 연산자
• 2개의 변수가 동일한 객체를 참조하고 있는지를 검사하는 연산자

if s is t :
print("2개의 변수는 동일한 객체를 참조하고 있습니다.")

if s is not t :
print("2개의 변수는 다른 객체를 참조하고 있습니다.")

• is는 두 객체가 저장하고 있는 데이터가 동일한지를


비교하는 것이 아님
 같은 참조(주소)값을 가지고 있는지를 비교
• 같은 내용을 가진 두 개의 객체라도 참조(주소)가 다르면,
즉 메모리 속에 다른 공간이 할당되어 있으면
is연산자는 false 반환
객체 참조
None 참조값
• review: 파이썬의 모든 것이 객체
• 변수가 아무것도 참조하지 않는다면 None으로 설정
myTV = None

if myTV is None :
print("현재 TV가 없습니다. ")

• None을 가지고 있는 변수를 이용하여


객체의 멤버를 호출하는 것은 오류가 됨
myTV = None

myTV.setChannel(5) #오류!
객체 참조
객체를 함수로 전달할 때
# 텔레비전을 클래스로 정의함
class Television:
def __init__(self, channel, volume, on):
self.channel = channel
self.volume = volume
self.on = on
def show(self):
print(self.channel, self.volume, self.on)

# 전달받은 텔레비전의 음량을 줄임


def setSilentMode(t): 숫자나 문자열과 같은
t.volume = 2 변경 불가능한 객체를 제외
# setSilentMode( )을 호출하여서
객체의 내용이 변경되는지를 확인 참조에 의한 호출 형태로 전달
myTV = Television(11, 10, True);
setSilentMode(myTV)
myTV.show( )

11 2 True
클래스 변수
인스턴스 변수: 객체를 통해서 사용(객체별로 별도 공간)

클래스 변수(정적 변수): 모든 객체에 대하 공유되는 공간


• C++의 static member variable 개념과 동일
클래스 변수
클래스 변수 Vs 인스턴스 변수
클래스 변수

인스턴스 변수

• 인스턴스 변수: 객체별로 가지는 자신만의 변수


• 클래스 변수: 모든 객체에 공통인 변수, 정적변수
클래스 변수
클래스 변수 Vs 인스턴스 변수
# 텔레비전을 클래스로 정의한다.
class Television:
serialNumber = 0 # 이것이 클래스 변수

def __init__(self, channel, volume, on):


self.channel = channel
self.volume = volume
self.on = on
Television.serialNumber += 1
# 객체 생성시마다 클래스 변수를 하나 증가함
# 클래스 변수의 값을 객체의 시리얼 번호로 함
self.number = Television.serialNumber

def show(self):
print(self.channel, self.volume, self.on, self.number)

myTV = Television(11, 10, True);


myTV.show( )
myTV2 = Television(11, 10, True);
myTV2.show( )

11 10 True 1
11 10 True 2
특수 메소드
파이썬에는 연산자(+, -, *, /)에 관련된
특수 메소드(special method)가 있음

이들 메소드는 우리가 객체에 대하여


+, -, *, /와 같은 연산을 적용하면 자동으로 호출됨:
객체간 연산자 대한 재정의
class Circle:
...
def __eq__(self, other): # ==은 이항 연산자 other은 r-value
return self.radius == other.radius
c1 = Circle(10)
c2 = Circle(10)
if c1 == c2:
print("원의 반지름은 동일합니다. ")
특수 메소드
특수 메소드 관련 연산자
연산자 메소드 설명
x+y __add__(Self, y) 덧셈

x-y __sub__(Self, y) 뺄셈

x*y __mul__(Self, y) 곱셈

x/y __truediv__(Self, y) 실수나눗셈

x // y __floordiv__(Self, y) 정수나눗셈

x%y __mod__(Self, y) 나머지

divmod(x, y) __divmod__(Self, y) 실수나눗셈과 나머지

x ** y __pow__(Self, y) 지수

x << y __lshift__(Self, y) 왼쪽 비트 이동

x >> y __rshift__(Self, y) 오른쪽 비트 이동

x <= y __le__(Self, y) less than or equal (작거나 같다)

x<y __lt__(Self, y) less than (작다)

x >= y __ge__(Self, y) greater than or equal (크거나 같다)

x>y __gt__(Self, y) greater than (크다)

x == y __eq__(Self, y) 같다

x != y __neq__(Self, y) 같지 않다
특수 메소드
__str__( )메소드
• 객체 안의 정보를 출력하는 방법을 정의하는 메소드
class Circle:
...
def __str__(self):
msg= “반지름값:”+str(self.radius)
return msg

c1 = Circle(10)
print(c1)
반지름값: 10
9주차 수업 정리

클래스는 속성과 동작으로 이루어진다.


속성은 인스턴스 변수로 표현되고 동작은 메소드로 표현된다.

객체를 생성하려면 생성자 메소드를 호출한다.


생성자 메소드는 __init__() 이름의 메소드이다.

인스턴스 변수를 정의하려면 생성자 메소드 안에서


self.변수이름 과 같이 생성한다.

클래스 변수는 객체간 공유되는 정적 공간이다.

You might also like