[Swift 기초] 접근제어
2022. 4. 13. 17:38ㆍSwift 기초 정리
728x90
//공부 기록용 포스팅입니다. 틀린 부분이 있을 경우 댓글로 알려주시면 감사합니다! 😎
스위프트의 접근제어는 모듈과 소스파일을 기반으로 설계되어있다.
1. 모듈
- 배포할 코드의 묶음 단위
- 하나의 프레임워크, 라이브러리, 애플리케이션이 모듈 단위가 될 수 있다.
- 스위프트에서는 import 키워드로 불러온다.
2. 소스파일
- 스위프트 소스 코드 파일
- 통상 파일 하나에 타입 하나만 정의하지만
- 소스파일 하나에 여러 타입(여러 개의 클래스, 구조체, 열거형)이나 함수 등 많은 것을 정의하거나 구현
3. 접근수준(Access Level)
- 각 타입(클래스, 구조체, 열거형 등)에 특정 접근수준을 지정할 수 있고, 타입 내부의 프로퍼티, 메서드, 이니셜라이저, 서브스크립트 각각에도 접근수준을 지정할 수 있다.
- open, public, internal, fileprivate, private
- 접근수준은 기본적으로 모듈과 소스파일에 따라 구분
접근수준 | 키워드 | 범위 | 비고 |
개방 접근수준 | open | 모듈 외부까지 | 클래스에서만 사용 |
공개 접근수준 | public | 모듈 외부까지 | |
내부 접근수준 | internal | 모듈 내부 | |
파일외부비공개 접근수준 | fileprivate | 파일 내부 | |
비공개 접근수준 | private | 기능정의 내부 |
3-1. 공개 접근수준 public
- 자신이 구현된 소스파일은 물론, 그 소스파일이 속해 있는 모듈, 그 모듈을 가져다 쓰는 모듈 등 모든 곳에서 사용할 수 있다.
- 우리가 사용하는 스위프트의 기본 요소는 모두 공개 접근 수준으로 구현 되어 있다고 생각하면 된다.
//스위프트 표준 라이브러리에 정의되어 있는 Bool 타입
/// A value type whose instances are either 'true' or 'false'.
public struct Bool {
/// Default-initialize Boolean value to 'false'.
public init()
}
3-2. 개방 접근수준 open
- 공개(public) 접근 수준 이상으로 높은 접근 수준
- 클래스와 클래스의 멤버에서만 사용할 수 있다.
- 공개 접근수준과 차이점
- 개방 접근 수준을 제외한 다른 모든 접근수준의 클래스는 그 클래스가 정의된 모듈안에서만 사용할 수 있다. (= 공개 접근수준과 개방 접근 수준은 모듈 외부에서도 사용할 수 있다.)
- 개방 접근 수준을 제외한 다른 모든 접근수준의 클래스 멤버는 해당 멤버가 정의된 모듈 안에서만 재정의 할 수 있다. (= 공개 접근수준과 개방 접근 수준의 클래스 멤버는 모듈 외부에서도 재정의 할 수 있다.)
- 개방(open) 접근수준의 클래스는 그 클래스가 정의된 모듈 밖의 다른 모듈에서도 상속할 수 있다.
- 개방(open) 접근수준의 클래스 멤버는 해당 멤버가 정의된 모듈 밖의 다른 모듈에서도 재정의(override)할 수 있다.
- 클래스를 개방(open) 접근수준으로 명시하는 것은 그 클래스를 다른 모듈에서도 부모 클래스로 사용하겠다는 목적으로 클래스를 설계하고 코드를 작성했음을 의미
//Foundation 프레임워크에 정의되어 있는 개방접근 수준의 NSString 클래스
open class NSString : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
open var length: Int { get }
open func character(at index: Int) -> unichar
public init()
public init?(coder aDecoder: NSCoder)
}
3-3. open과 public 접근수준의 선택
- 라이브러리 혹은 프레임 워크를 설계할 때 해당 모듈을 사용하는 프로그래머가 이 타입을 사용할 수 있도록 하려면 open 혹은 public 공개수준으로 타입을 정의하면 된다.
- open(개방): 사용자가 상속받아 사용 O or 상속 후 재정의 O
- public(공개): 상속 X, 재정의 X
- open 및 public 접근 수준이 아닌 다른 클래스 및 타입은 모듈 외부에서 접근할 수 없다.
3-4. 내부 접근 수준 internal
- 기본적으로 모든 요소에 암묵적으로 지정하는 기본 접근 수준
- 소스파일이 속해 있는 모듈 어디서든 사용할 수 있다. 다만 그 모듈을 가져다 쓰는 외부 모듈에서는 접근할 수 없다.
- 외부에서 사용할 클래스나 구조체가 아니며, 모듈 내부에서 광역적으로 사용할 경우 내부 접근 수준을 지정
3-5. 파일외부비공개 접근수준 fileprivate
- 요소가 구현된 소스파일 내부에서만 사용할 수 있다.
3-6. 비공개 접근수준 private
- 가장 한정적인 범위
- 기능을 정의하고 구현한 범위 내에서만 사용할 수 있다.
- 같은 소스파일 안에 구현한 다른 타입이나 기능에서도 사용할 수 없다.
3-7. 접근수준
(높은 접근수준) open ←→ public ←→ internal ←→ fileprivate ←→ private (낮은 접근수준)
- 상위 요소보다 하위 요소가 더 높은 접근수준을 가질 수 없다.
- 비공개 접근 수준으로 정의한 구조체 내부의 프로퍼티로 내부수준이나 공개수준을 갖는 프로퍼티를 정의할 수 없다.
- 비공개 접근수준 AClass에서 정의한 someMethod() 메서드도 공개 접근 수준을 부여해도 비공개 접근수준으로 취급
- 공개 접근 수준의 함수에 비공개 접근수준의 매개변수나 리턴타입으로 사용할 수 없다.
private class AClass {
// 공개 접근수준을 부여해도 AClass의 접근수준이 비공개 접근수준이므로
// 이 메서드의 접근수준도 비공개 접근수준으로 취급됩니다.
public func someMethod() {
// ...
}
}
//비공개 접근수준 AClass에서 정의한 someMethod() 메서드도 공개 접근 수준을 부여해도 비공개 접근수준으로 취급
// AClass의 접근수준이 비공개 접근수준이므로
// 공개 접근수준 함수의 매개변수나 반환 값 타입으로 사용할 수 없습니다.
public func someFunction(a: AClass) -> AClass {
// 오류 발생!
return a
}
//공개 접근 수준의 함수에 비공개 접근수준의 매개변수나 리턴타입으로 사용할 수 없다.
3-8. private와 fileprivate
- fileprivate 접근 수준은 같은 파일 어떤 코드에서 접근할 수 있다
- private 접근 수준은 같은 파일 내부에 다른 타입의 코드가 있더라도 접근할 수 없다.
- 자신을 확장하는 extension 코드가 같은 파일에 존재하는 경우에는 접근할 수 있다.
public struct SomeType {
private var privateVariable = 0
fileprivate var fileprivateVariable = 0
}
// 같은 타입의 익스텐션에서는 private 요소에 접근 가능
extension SomeType {
public func publicMethod() {
print("\\(self.privateVariable), \\(self.fileprivateVariable)")
}
private func privateMethod() {
print("\\(self.privateVariable), \\(self.fileprivateVariable)")
}
fileprivate func fileprivateMethod() {
print("\\(self.privateVariable), \\(self.fileprivateVariable)")
}
}
struct AnotherType {
var someInstance: SomeType = SomeType()
mutating func someMethod() {
// public 접근수준에는 어디서든 접근 가능
self.someInstance.publicMethod() // 0, 0
// 같은 파일에 속해 있는 코드이므로 fileprivate 접근수준 요소에 접근 가능
self.someInstance.fileprivateVariable = 100
self.someInstance.fileprivateMethod() // 0, 100
// 다른 타입 내부의 코드이므로 private 요소에 접근 불가! 오류!
// self.someInstance.privateVariable = 100
// self.someInstance.privateMethod()
}
}
var anotherInstance = AnotherType()
anotherInstance.someMethod()
4. 읽기 전용 구현
- 저장 프로퍼티를 구현할 때는 허용된 접근수준에서 프로퍼티 값을 가져갈 수 있다. 이때 값을 변경할 수 없도록 구현하고 싶다면 → 설정자(Setter)만 더 낮은 접근수준을 갖도록 제한
- 설정자: set
- 접근자: get
- 요소의 접근 수준 키워드 뒤에 {접근수준}(set)처럼 표현하면 설정자의 접근수준만 더 낮도록 지정할 수 있다.
public private(set) var publicGetOnlyStoredProeprty: Int = 0
- 설정자의 접근 수준 제한은 프로퍼티, 서브스크립트, 변수 등에 적용될 수 있다.
- 해당 요소의 접근수준보다 같거나 낮은 수준으로 제한
public struct SomeType {
// 비공개 접근수준 저장 프로퍼티 count
private var count: Int = 0
// 공개 접근수준 저장 프로퍼티 publicStoredProperty
public var publicStoredProperty: Int = 0
// 공개 접근수준 저장 프로퍼티 publicGetOnlyStoredProperty
// 설정자는 비공개 접근수준
public private(set) var publicGetOnlyStoredProperty: Int = 0
// 내부 접근수준 연산 프로퍼티 internalComputedProperty
internal var internalComputedProperty: Int {
get {
return count
}
set {
count += 1
}
}
// 내부 접근수준 연산 프로퍼티 internalGetOnlyComputedProperty
// 설정자는 비공개 접근수준
internal private(set) var internalGetOnlyComputedProperty: Int {
get {
return count
}
set {
count += 1
}
}
}
var someInstance: SomeType = SomeType()
// 외부에서 접근자, 설정자 모두 사용 가능
print(someInstance.publicStoredProperty) // 0
someInstance.publicStoredProperty = 100
// 외부에서 접근자만 사용 가능: 설정자는 비공개 접근수준(private)
print(someInstance.publicGetOnlyStoredProperty) // 0
//someInstance.publicGetOnlyStoredProperty = 100 // 오류 발생
// 외부에서 접근자, 설정자 모두 사용 가능
print(someInstance.internalComputedProperty) // 0
someInstance.internalComputedProperty = 100
// 외부에서 접근자만 사용 가능: 설정자는 비공개 접근수준(private)
print(someInstance.internalGetOnlyComputedProperty) // 1
//someInstance.internalGetOnlyComputedProperty = 100 // 오류 발생
참고하였습니다. 감사합니다.
https://yagom.net/courses/swift-basic/lessons/접근제어/
728x90
'Swift 기초 정리' 카테고리의 다른 글
[Swift 기초] 연산자 오버로딩 (0) | 2023.07.11 |
---|---|
[Swift 코테 기초] 고차함수 (0) | 2022.04.12 |
[Swift 기초] 오류처리 (0) | 2022.04.11 |
[Swift 기초] 익스텐션 (0) | 2022.04.05 |
[Swift 기초] 프로토콜 (0) | 2022.04.05 |