접근 제어
class SomeClass {
private var name = "이름"
func nameChange(name: String) {
if name == "길동" {
return
}
self.name = name
}
}
let object1 = SomeClass()
5가지 접근 수준
- open - 다른 모듈에서도 접근가능 / 상속 및 재정의도 가능 (제한 낮음)
- public - 다른 모듈에서도 접근가능 (상속/재정의 불가)
- 구조체에서 가장 넓은 범위 (구조체는 어차피 상속/재정의 불가)
- internal - 같은 모듈 내에서만 접근가능 (디폴트)
- fileprivate - 같은 파일 내에서만 접근가능
- private - 같은 scope내에서만 접근가능 (제한 높음)
모듈(module): 프레임워크, 라이브러리, 앱 등 import해서 사용할 수 있는 외부의 코드
기본 원칙
- 타입은 타입을 사용하는 변수(속성)나 함수(메서드)보다 높은 수준으로 선언되어야 한다
internal var some: String = "접근가능"
func someFunction(a: Int) -> Bool {
print(a)
return true
}
기본 문법
public class SomePublicClass {}
internal class SomeInternalClass {}
fileprivate class SomeFilePrivateClass {}
private class SomePrivateClass {}
public var somePublicVariable = 0
internal let someInternalConstant = 0
fileprivate func someFilePrivateFunction() {}
private func somePrivateFunction() {}
class SomeInternalClass1 {}
let someInternalConstant1 = 0
관습적인 패턴
class SomeOtherClass {
private var _name = "이름"
var name: String {
return _name
}
}
class SomeAnotherClass {
private(set) var name = "이름"
}
커스텀 타입의 접근 제어
- 타입의 내부 멤버는 타입 자체의 접근 수준을 넘을 수 없다
- 타입이 internal로 선언되면 내부 멤버는 internal 이하만 가능
public class SomePublicClass {
open var someOpenProperty = "SomeOpen"
public var somePublicProperty = "SomePublic"
var someInternalProperty = "SomeInternal"
fileprivate var someFilePrivateProperty = "SomeFilePrivate"
private var somePrivateProperty = "SomePrivate"
}
- 타입을 private으로 선언하는 것은 의미가 없다 -> fileprivate으로 동작한다
private class SomePrivateClass {
open var someOpenProperty = "SomeOpen"
public var somePublicProperty = "SomePublic"
var someInternalProperty = "SomeInternal"
var someFilePrivateProperty = "SomeFilePrivate"
private var somePrivateProperty = "SomePrivate"
}
- 내부 멤버가 명시적 선언을 하지 않으면, 접근 수준은 internal로 유지
- 타입의 접근 수준을 따라가는 건 아님!!
open class SomeClass {
var someProperty = "SomeInternal"
}
상속과 확장의 접근 제어
상속
- 타입 관련 : 상속해서 만든 서브클래스는 상위클래스보다 높은 접근 수준을 가질 수 없다
- 멤버 관련 : 동일 묘듈에서 정의한 클래스의 상위 멤버에 접근 가능하면, (접근 수준 올려서) 재정의 가능
public class A {
fileprivate func someMethod() {}
}
internal class B: A {
override internal func someMethod() {
super.someMethod()
}
}
확장
- 기본 : 원래 본체와 동일한 접근 수준 유지하고, 본체 멤버에는 기본적인 접근 가능
public class SomeClass {
private var somePrivateProperty = "somePrivate"
}
extension SomeClass {
func somePrivateControlFunction() {
somePrivateProperty = "접근 가능"
}
}
속성의 접근 제어
- 변수 및 속성, 서브스크립트에 쓰기 수준을 읽기 수준보다 낮은 접근 수준으로 설정 가능
- 쓰기의 수준이 더 높은 건 불가능하다
struct TrackedString {
private(set) var numberOfEdits = 0
var value: String = "시작" {
didSet {
numberOfEdits += 1
}
}
}