접근 제한자는 코드 요소에 대한 외부 접근을 제한하여 모듈 간의 접근성과 보안을 조절한다. 각 타입에 특정 접근수준을 지정할 수 있고, 타입 내부의 프로퍼티, 메서드, 이니셜라이저, 서브스크립트 각각에도 접근수준을 지정할 수 있다. 접근 수준을 명시하는 키워드는 다음과 같다.
open : 모든 소스 파일에서 해당 level 접근 가능 + 모든 곳에서 서브클래싱 가능public : 모든 소스 파일에서 해당 level 접근 가능 + 같은 모듈 내에서만 서브클래싱 가능internal : 같은 모듈 내에서만 접근 가능fileprivate : 같은 소스파일 내에서만 접근 가능private : 클래스 내부에서만 접근 가능❇︎모듈 : 배포할 코드의 묶음 단위이다. 보통 프레임워크, 라이브러리, 애플리케이션을 말함.
❇︎소스파일 : 소스파일은 하나의 스위프트 소스 코드 파일을 의미한다.
open은 가장 높은 접근 수준을 가진 키워드로, 클래스와 클래스의 멤버에서만 사용할 수 있고 다른 모듈에서 서브클래싱이 가능하다. open으로 클래스를 개방접근수준으로 명시하는 것은 그 클래스를 다른 모듈에서도 수퍼클래스로 사용하겠다는 의미로 해당 클래스를 설계하고 만들었다는 것을 의미한다.
open class Vehicle {
open func startEngine() {
print("Engine started")
}
}
open class Car: Vehicle {
open var carType: String = "Sedan"
}
open 클래스는 그 클래스가 정의된 모듈 밖의 다른 모듈에서도 상속할 수 있다. (다른 접근수준은 불가능)open 클래스의 멤버는 해당 멤버가 정의된 모듈 밖의 다른 모듈에서도 재정의할 수 있다. (다른 접근수준은 불가능)public은 자신이 구현된 소스파일, 그 소스파일이 속해있는 모듈, 그 모듈을 가져다 쓰는 모듈 등 어디서든 쓰일 수 있다. public은 주로 프레임워크에서 외부와 연결될 인터페이스를 구현하는데 많이 사용한다.
public struct Point {
public var x: Int
public var y: Int
public init(x: Int, y: Int) {
self.x = x
self.y = y
}
public mutating func moveByX(_ deltaX: Int, y deltaY: Int) {
self.x += deltaX
self.y += deltaY
}
}
public과 open 접근수준은 라이브러리나 프레임워크 설계시에 사용한다.
internal은 모든 요소에 암묵적으로 지정하는 디폴트 접근 제어자이다. 소스 파일이 속해있는 모듈 어디에든 접근할 수 있지만 외부 모듈에서는 접근할 수 없다. 보통 외부에서 사용할 클래스나 구조체가 아니며, 모듈 내부에서 광역적으로 사용할 경우 내부 접근 수준을 지정한다.
internal class InternalClass {
internal var internalProperty: Int = 10
internal func doSomethingInternally() {
print("Internal operation performed")
}
}
internal let internalConstant = 20
fileprivate은 키워드가 구현된 소스 파일 내부에서만 사용할 수 있다. 서로 다른 클래스가 같은 하나의 소스파일에 정의되어있고 fileprivate로 선언되어 있다면 두 클래스는 접근할 수 있다.
class OuterClass {
fileprivate var outerVariable = 30
fileprivate func outerFunction() {
print("Outer function called")
}
fileprivate class InnerClass {
fileprivate func innerFunction() {
print("Inner function called")
}
}
}
private은 가장 제한적인 접근제어자이다. private으로 지정된 요소는 그 니으을 정의하고 구현한 범위 내에서만 사용할 수 있다. 같은 소스파일 안에 구현한 다른 타입이나 기능에서도 사용할 수 없다.
class MyClass {
private var privateVariable = 40
private func privateFunction() {
print("Private function called")
}
}
✅ Static은 접근제어자가 아니다!!
static은 멤버를 타입 자체에 속하도록 만드는 키워드이다. 일반적으로 클래스나 구조체의 인스턴스와는 관계없이 타입 자체에 속하는 멤버를 정의할 때 사용된다. 즉, 해당 멤버는 타입 자체에 속하므로 타입을 통해 직접적으로 접근할 수 있다. (만약 클래스 안에 static이라고 프로퍼티를 만들면 그 프로퍼티는 클래스의 타입으로 불러올 수 있는 것!!)
class SomeClass { static var staticProperty = 0 class var classProperty: Int { return 0 } static func staticMethod() { print("This is a static method") } class func classMethod() { print("This is a class method") } } let instance = SomeClass() print(SomeClass.staticProperty) // 직접적인 접근 SomeClass.staticMethod() // 직접적인 접근