프로퍼티의 get, set
출처
이 글은 "Young Kim" 님의 글을 참고하여 작성한 글 임을 미리 밝힙니다
get 과 set
예시를 통한 설명
var myProperty: Int {
get {
return myProperty
}
set(newValue) {
myProperty = newValue
}
}
print(myProperty) // myProperty 출력
myProperty = 123 // newValue 값은 123
위의 예시를 보고 내가 처음 든 생각은 get은 가지고 있는 값을 돌려주는것이고
set은 어떤 새로운 값을 넣어주는것이다
라고 생각이 들었다.
get, set을 사용하려면 ??
위의 예시처럼 사용하게 되면 안된다.
그 이유는 재귀적으로 자기 자신의 get, set을 호출하기 때문이다
get, set을 사용하려면 실제 값을 저장 할 저장공간이 따로 필요하다
예시를 통한 설명
var storageOfMyProperty: Int
var myProperty: Int {
get {
return storageOfMyProperty
}
set(newValue) {
storageOfMyProperty = newValue
}
}
"storageOfMyProperty" 는 실제로 값이 저장되는 변수이다
외부에서 myProperty의 값에 접근하거나 새로운 값을 할당하면 실제로 값이 저장되는 곳은
"storageOfMyProperty"이다.
get과 set의 활용
1. 프로퍼티에 값이 할당 될 때 적절한 값인지 검증
class Company {
var storageOfMembers: Int = 5
var members: Int {
get {
return storageOfMembers
}
set(newValue) {
if (newValue < 1) {
print("직원수는 한명보다 작을 수 없다")
} else {
storageOfMembers = newValue
}
}
}
}
Company 클래스 안에 직원수를 나태내는 members 프로퍼티가 있다
직원수는 음수가 될 수 없으므로 members 값을 바꿀 때는 검증 할 필요가 있다
set의 스코프 내에 있는 newValue 값을 사용하여 프로퍼티의 값이 바뀌기 전에
Validation 할 수 있다
2. 다른 프로퍼티 값에 의존적인 프로퍼티를 관리 할 때
class Company {
var storageOfMembers: Int = 5
var members: Int {
get {
return storageOfMembers
}
set(newValue) {
if (newValue < 1) {
print("직원수는 한명보다 작을 수 없다")
}else{
storageOfMembers = newValue
}
}
}
var teamDinnerCost: Int {
get {
return storageOfMembers * 100000
}
}
}
회식비인 teamDinnerCost 프로퍼티가 추가 되었는데, 회식비는 직원 수에 비례하기 때문에
storageOfMembers에 의존적이다.
storageOfMembers 프로퍼티에 get을 사용하면 직원수에 비례하여 계산된 회식비를 반환하도록
할 수 있다.
이런 경우에는 teamDinnerCost의 값을 따로 신경쓰지 않아도 된다
또한 get만을 구현했으므로 외부에서 teamDinnerCost의 값을 변경하려고 하면 에러가 발생한다
따라서 회식비는 직원수에 비례하여 정해진 값 만을 반환한다
3. 프로퍼티를 private하게 사용하기 위해
private(set) var myProperty: Int = 10
위의 예시와 같은 경우 myProperty는 "internal getter" 와 "private setter"을 얻게된다
myProperty가 선언된 파일내에서만 값을 수정 할 수 있고 외부에서는 값을 수정 할 수 없다
그러나 myProperty의 값을 얻는것은 모듈내 어디서든 가능하다
public private(set) var myProperty: Int = 10
위와 같은 경우에는 "internal getter"이 아닌 "public getter"로 선언되었다
위와 같이 선언시 myProperty의 값은 어디서든 접근이 가능하다
다만 이렇게 선언할 경우 class를 public 클래스로 선언 해 주어야 한다.