#1. 접근 지정자(Access Modifier)
객체 지향 프로그래밍을 위해 java의 경우 접근 지정자를 지원한다. 접근 지정자는 클래스 내에서 멤버의 접근을 제한하는 역할을 하는데 java에는 총 4가지의 접근 지정자가 있다.
- public : 모든 접근을 허용한다. 어떠한 클래스가 접근을 하든 모두 허용
- protected : 상속받은 클래스 또는 같은 패키지에서만 접근이 가능
- default : 기본 제한자로써 아무것도 붙지 않고, 같은 클래스 내부와 같은 패키지 내에서만 접근 가능
- private : 외부에서 접근이 불가능. 즉, 같은 클래스 내에서만 접근 가능
표를 통해 쉽게 이해하자.
한정자 | 클래스 내부 | 동일 패키지 | 하위 클래스 | 그 외의 영역 |
public | o | o | o | o |
protected | o | o | o | x |
default | o | o | x | x |
private | o | x | x | x |
<파이썬 관행적 정보은닉>
파이썬은 속성과 메소드가 전부 공개되어 있기 때문에 속성을 숨길 방안이 없다.
내부 속성 이름을 알고 있다면 직접 접근해서 조회나 갱신을 막는 것이 불가능하지만, 직접 호출하는것은 막는 방법이 존재한다. 이를 표로 표현하면 다음과 같다.
이름 | 타입 | 의미 |
name | public | 이 속성들은 클래스 정의부 안과 밖에서 자유롭게 사용이 가능하다. |
_name | protected | 상속 클래스 정의부 안이면 클래스 정의부 밖에서 사용될 수 없다. |
__name | private | 이 속성들은 일반적으로 접근 할 수도 없고 보이지도 않는다. 클래스 정의부 내부가 아니면 직접 호출(print)하는 것이 불가능하다. 하지만 파이썬 속성의 정확한 이름을 알고있다면 직접 조회(다른 변수에 할당),갱신이 가능하다. |
<파이썬 접근자 설정자>
# 접근자 (getter)
접근자를 설정하는 방법은 두 가지가 있다
- 클래스 내부 메소드를 private 속성을 return 하도록 하고 인스턴스에서 호출하도록 하는 방법
- property를 이용하는 방법
1. 클래스 내부 메소드를 이용하는 방법
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
# Family 클래스 생성
class Family:
def __init__(self, father="아버지", mother="어머니", me='내이름'):
self.__ancestor = '단군 할아버지' # private
self.father = father
self.mother = mother
self.me = me
def info(self):
print('아버지 : {}, 어머니 : {}, 나 : {}'.format(self.father, self.mother, self.me))
def getancestor(self):
return self.__ancestor
Fam3 = Family() # 새로운 인스턴스 생성
Fam3.__ancestor # 오류
Fam3.getancestor() # 은닉정보 호출
|
cs |
2. property를 이용하는 방법
property를 사용한다 해도 기본으로 퍼블릭이므로 정확한 변수명을 안다면 모든 것을 조회 가능하다.
메소드 바로 위에 @property를 지정하면 함수명으로 하나의 인스턴스를 만들고 그 내부의 getter 메소드에 등록한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
# Family 클래스 생성
class Family:
def __init__(self, father="아버지", mother="어머니", me='내이름'):
self.__ancestor = '단군 할아버지' # private
self.father = father
self.mother = mother
self.me = me
def info(self):
print('아버지 : {}, 어머니 : {}, 나 : {}'.format(self.father, self.mother, self.me))
@property # property 사용법
def ancestor(self): # ancestor 인스턴스 생성 -> getter 메소드
return self.__ancestor
Fam4 = Family() # 새로운 인스턴스 생성
Fam4.ancestor # 은닉정보 호출
|
cs |
# 설정자 (setter)
설정자를 설정하는 방법은 두 가지가 있다.
- 클래스 내부의 private 속성을 설정하도록 하는 메소드를 만든다.
- @함수명.setter를 은닉 인스턴스 변수를 설정하는 메소드 상단에 적어준다. 단, setter는 property 하단에 위치해야 한다.
1. 클래스 내부의 메소드를 이용하는 방법
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
# Family 클래스 생성
class Family:
def __init__(self, father=None, mother=None, me=None, ancestor='단군 할아버지'):
self.__setancestor(ancestor)
self.father = father
self.mother = mother
self.me = me
def info(self):
print('아버지 : {}, 어머니 : {}, 나 : {}'.format(self.father, self.mother, self.me))
# 은닉형태의 설정자 메소드를 생성한다.
def __setancestor(self, ancestor):
self.__ancestor = ancestor
# 생성자 메소드를 통해 지정한 은닉 인스턴스 변수를 호출하는 메소드
def getancestor(self):
return self.__ancestor
Fam5 = Family() # 인스턴스 생성
Fam5.getancestor() # 생성자를 활용해 은닉정보 확인
|
cs |
2. @함수명.setter를 이용하는 방법
갱신을 위해 setter를 이용이 가능하다 하지만 이 역시 내부의 속성 이름을 알고 있다면 메소드 대신 직접 접근해 조회나 갱신이 가능하다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
# Family 클래스 생성
class Family:
def __init__(self, father=None, mother=None, me=None):
self.__ancestor = '단군 할아버지'
self.father = father
self.mother = mother
self.me = me
def info(self):
print('아버지 : {}, 어머니 : {}, 나 : {}'.format(self.father, self.mother, self.me))
@property # property를 통해 ancestor 인스턴스 만들어짐
def ancestor(self): # 내부에 이 메소드가 getter로 등록
return self.__ancestor
@ancestor.setter # setter를 통해 ancestor 인스턴스에 dot 연산자를 이용
def ancestor(self, value): # setter로 프로퍼티를 만들면 동일한 메소드 등록
self.__ancestor = value
print('클래스 내부 namespace', locals())
# 'ancestor': <property object at 0x000002028703FCC8> -> ancesotr 속성이 property 인스턴스가 됨
Fam5 = Family() # 인스턴스 생성
print(Fam5.ancestor) # 접근자를 통해 은닉정보 단군 할아버지 확인
Fam5.ancestor = '조지 워싱턴' # 설정자를 통해 은닝정보 재 설정
print(Fam5.ancestor) # 변경된 은닉정보 조지 워싱턴 확인
|
cs |
해당 코드의 실행 결과를 확인하면
클래스 내부의 namespace에는 ancestor라는 property 인스턴스가 있음을 확인 할 수 있고, 이미 지정되어 있는 은닉정보를 설정자를 통해 갱신이 가능하다는 사실을 확인 가능하다.
'프로그램 > 파이썬' 카테고리의 다른 글
클래스 생성자, 문자열화, 특수 메소드 (0) | 2020.07.31 |
---|---|
클래스 정의와 self (0) | 2020.07.30 |
객체 지향 프로그래밍 과 클래스 (0) | 2020.07.30 |