Access Control(접근제어)는 다른 소스 파일 및 모듈의 코드에서, 코드의 일부에 대한 접근을 제한합니다.
예를 통해서 한번 Open 과 Public의 차이점을 알아보자.
// MiroFramework라면
open class OpenClass {
public init(){}
}
public class PublicClass {
public init(){}
}
import MiroFramework
class ViewController: UIviewcontroller {
override func viewDidLoad() {
super.viewDidLoad()
let openClassInstance = OpenClass()
let publicClassInstance = PublicClass()
}
}
class SubClass: OpenClass() // OK!
class SubClass: PublicClass() // Error!
그러면 public 제어 레벨 및 internal, file-private, private 경우에는 싹 다 서브클래싱이 불가능할까?
그건 아니다! 같은 framework안에서는 서브클래싱이 가능하다. 즉, MiroFramework안에서는 서브클래싱이 가능하다.
by. Zeddios
📌 open class : Framework내부, Framework외부 (즉 어디서든) 서브클래싱이 가능
public class와 더 제한적인 접근 수준들(internal, File-private, private class) : Framework내부에서만 서브클래싱이 가능
애초에 public의 경우 subclass로 만들수가 없으므로 open 접근제어만 고려해보자!
// MiroFramework에서
open class OpenClass {
public init(){}
open func someMethod(){}
}
// error
class SubClass: OpenClass{
override func someMethod(){
print("")
}
}
반면에!!
// MiroFramework에서
open class OpenClass {
public init(){}
public func someMethod(){}
}
// OK
class SubClass: OpenClass{
override func someMethod(){
print("")
}
}
그러나, 앞서 서브 클래싱과 같게 같은 framework내에서는 override가 가능하다.
📌 **open : class, class 멤버는 정의된 모듈 내에서나, 그 모듈을 import하는 외부 모듈에서나 서브클래싱이나 override가 잘 된다"**public, internal, File-private, private : class, class멤버는 정의된 모듈 내에서만 서브클래싱이나 override가 된다"
⇒ internal 접근은 엔티티가 정의 모듈의 모든 소스 파일 내에서 사용되지만, 해당 모듈 외부의 소스파일에서는 사용되지 않도록 합니다. 일반적으로 App이나 Framework의 내부 구조를 정의할 때 internal 접근을 사용합니다.
즉, 모듈 내에서만 사용이 가능하다!
기본 default가 싹 다 internal이다, 따라서 internal이라는 단어가 없어도 다 internal인 것!
예를 통해서 이해해보자
// MiroFramework에서
class OpenClass {
public init(){}
func someMethod(){}
}
import MiroFramework
class ViewController: UIviewcontroller {
override func viewDidLoad() {
super.viewDidLoad()
// error
let openClassInstance = OpenClass()
}
}
// MiroFramework에서
open class OpenClass {
public init(){}
func someMethod(){}
}
import MiroFramework
class ViewController: UIviewcontroller {
override func viewDidLoad() {
super.viewDidLoad()
let openClassInstance = OpenClass()
// 에러
openopenClassInstance.someMethod()
}
}
internal이 모듈 내에서 사용이 가능하다면, file-private의 경우 소스 파일 내에서만 사용이 가능하다.
fileprivate class FileprivateClass{
public init() {}
}
private var fileprivateInstance = FileprivateClass()
private class A : FileprivateClass {} // Private or fileprivate을 붙혀준다.
open class OpenClass {
fileprivate func someMethod() {}
}
class A : OpenClass{
override func someMethod() {
print("Hello")
}
}
⇒ private접근을 사용하면 단일 정의 내에서만 사용되는 특정 기능 조각의 구현 상세 내역을 숨길 수 있습니다.
private class PrivateClass{
public init() {}
}
private let someInstance = PrivateClass() //OK
private class PrivateClass{
public init() {}
private var name = "Miro"
}
class Test {
private let someInstance = PrivateClass()
func someMethod(){
print(**someInstance.name**) //Error!
}
}
import
를 해주어야된다.예)
// module contactManager (target contactManager)
public var name: String = "module A"
var number: Int = 1
// module ContactManagerUI (target ContactManagerUI)
import contactManager
print(name) // OK!
print(number) // error
@testable
@testable
를 추가해주면 internal 메소드, 프로퍼디도 접근이 가능해진다!🥳출처
Access Control