# 접근제어 개념
객체지향에서의 개념 중 은닉화 구현을 위해 접근제어 키워드를 사용한다.
스위프트 접근제어 수준은 5가지가 있다.
- open - 다른 모듈에서도 접근 가능, 상속 및 재정의까지 가능 (클래스 )
- public - 다른 모듈에서도 접근 가능, 상속 및 재정의는 불가 (구조체)
- internal - 같은 모듈 내에서만 접근 가능 (디폴트)
- fileprivate - 같은 파일에서만 접근 가능
- private - 같은 스코프 내에서만 접근 가능
클래스 속성에서만 접근제어를 사용할 수 있는 것은 아니다.
- 타입(클래스/구조체/열거형/스위프트 기본타입 등)
- 변수/속성
- 함수/메서드(생성자, 서브스크립트 포함)
- 프로토콜도 특정영역으로 제한될 수 있음
# 원칙
타입은 해당 타입을 사용하는 변수나 함수보다 더 퍼블릭한 수준으로 선언해야한다. 함수의 경우 파라미터와 리턴타입의 접근제어 수준이 더 퍼블릭해야한다.
아래는 접근제어를 사용하는 관습적 패턴이다.
- 프라이빗 속성명은 앞에 언더바를 붙인다.
- 저장속성의 setter는 프라이빗으로 제한한다.
class SomeOtherClass {
private var _name = "이름" // 쓰기 - private
var name: String { // 읽기 - internal
return _name
}
}
// 저장속성의 (외부에서) 쓰기를 제한하기 ⭐️
class SomeAnotherClass {
private(set) var name = "이름" // 읽기 - internal / 쓰기 - private
}
커스텀 타입 접근제어
클래스 및 구조체와 같은 커스텀 타입의 접근 제어 수준은 내부 멤버의 접근제어 수준에 영향을 준다. 즉 커스텀타입 자체의 타입 접근 수준이 internal이라면 멤버는 public이나 open으로 선언하더라도 멤버 접근 수준도 internal로 작동한다.
내부 멤버를 명시적으로 선언하지 않는다면 접근 수준은 internal로 세팅된다.
커스텀 타입을 private으로 설정하는 것은 사실상 의미가 없다. 자동으로 fileprivate과 동일하게 동작한다.
A 접근수준이 B보다 높다는 것은 A 접근수준이 B보다 퍼블릭하다는 것을 의미한다.
클래스 상속시 자식 클래스가 상위 클래스보다 접근수준이 높으면 안된다. 반면 부모클래스를 상속한 자식클래스의 멤버에서 상위클래스 메서드를 재정의할때 접근 수준을 더 높여도 된다.
확장의 경우 본체 타입의 동일한 접근 수준을 유지한다. 본체 타입이 private 멤버이더라도 확장에서는 접근 가능하다.
쓰기 제한 접근수준 낮추기
struct TrackedString {
private(set) var numberOfEdits = 0 // setter에 대해서만 private 선언
// 속성 관찰자
var value: String = "시작" {
didSet {
numberOfEdits += 1
}
}
}
위 코드에서 numberOfEdits
멤버의 읽기는 문제없이 이루어진다.