Swift의 접근제어는 모듈과 소스파일에 기반을 두고 있습니다.
모듈은 코드를 배포하는 단일 단위로 하나의 프레임워크나 앱 단위로 하고 다른 모듈에서 import
키워드를 사용하여 import 됩니다.
접근레벨은 open(높다) ----- Private(낮다)로 봅니다.
public
과 같이 선언한 모듈이 아닌 다른 모듈에서 사용가능합니다. 하지만 public
과는 달리 다른 모듈에서 오버라이드와 서브클래싱까지 가능합니다.Internal
은 기본 접근레벨로서 접근레벨을 따로 명시해주지 않으면 Internal
로 설정 됩니다.낮은 접근레벨을 가진 하나의 개체가 높은 접근레벨을 가진 개체의 안에서 선언될 수 없다는 것이다.
예로 들면,
private func calcultorMoney() {
public var budget: Int = 10000 // ERROR
}
위의 코드 처럼 private로 선언된 함수안에 private보다 낮은 접근레벨로 선언된 변수, 상수 등이 선언될 수 없다.
커스텀 타입에 특정 접근레벨을 지정할 수 있습니다. 커스텀 타입에 특정 레벨을 지정하게 되면 그 타입안에 프로퍼티, 파라미터, 리턴타입은 기본적으로 해당 타입의 접근레벨을 따르게 됩니다.
하지만 public으로 설정된 타입의 멤버는 기본적으로 internal레벨을 가지고 있다. public API를 만들시 노출되지 말아야 할 API가 실수로 노출되지 않기 위함입니다.
튜플타입 자체적으로 접근레벨을 선언하지 않고 사용하는 클래스, 구조체, 열거형, 함수 등에 따라 자동으로 최고 접근레벨을 부여 받습니다. 그리고 그 중 가장 낮은 레벨의 접근 권한을 갖게 됩니다. 그렇기 때문에 튜플은 명시적으로 접근권한을 명시하지 않습니다.
함수 타입의 접근레벨은 함수의 파라미터 타입과 리턴타입의 접근레벨 중 최소의 접근레벨로 지정되어야 합니다.
열거형에서 각 case는 enum의 접근레벨을 따르고 각 case별로 접근레벨을 지정할 수 없다.
원시값과 연관값을 사용하는 타입의 경우 반드시 그 타입보다 높은 접근레벨을 가져야 합니다. internal 접근 레벨을 갖고 있는 열거형 타입에서 private 접근레벨을 갖는 원시값을 사용할 수 없습니다.
private, file-private로 선언된 타입의 중첩 타입은 자동으로 private, file-private 접근레벨을 갖습니다. public, internal로 선언된 타입의 중첩 타입은 internal 접근레벨을 갖습니다. public 접근레벨로 선언된 타입에서 public으로 선언된 중첩 타입을 사용하려면 명시적으로 중첩 타입에 public을 적어주어야 합니다.
서브클래스는 수퍼클래스보다 더 높은 접근레벨을 가질 수 없습니다. 예를 들어, 클래스 A는 file-private 메서드 someMethod()
를 가진 public 접근레벨을 가진 클래스입니다. 클래스 B는 접근레벨이 internal 보다 높은 클래스 A의 서브클래스입니다. 그럼에도 불구하고, 클래스 B는 someMethod()
의 원래 접근레벨보다 높은 internal 접근레벨로 someMethod()
의 override를 제공한다.
public class A {
fileprivate func someMethod() {}
}
internal class B: A {
override internal func someMethod() {}
}