• [Swift] 🧲접근제어(Access Control)

    2024. 3. 2.

    by. 멋진개발자

    📚 접근제어의 기본을 알아보자

    코드의 세부 구현 내용을 숨기는 것이 가능하도록 만드는 개념 ( 은닉화 가능 )

     

    ❓접근제어가 필요한 이유는 무엇      

    • 속성과 메서드를 숨기기 가능
    • 코드의 세부 구현 내용을 숨기는 것이 가능 (객체지향-은닉화)
    • 코드의 영역을 분리시켜, 효율적인 관리 가능
    • 컴파일 시간 단축(컴파일러가 변수의 사용범위를 인지가능)
    • apple이 자신들이 원하는 코드를 숨길 수 있음

     

    🔍 접근제어자 5가지를 알아보자

    1️⃣ open

    - open 접근 제어자는 가장 높은 수준의 접근제어자, 다른 모듈에서도 해당 클래스나 메서드를 서브클래싱 하거나, 오버라이딩 할 수 있습니다. 보통 외부 라이브러리를 만들고 사용할 때 유용합니다. open으로 선언된 클래스나 메서드를 상속하거나 재정의해서 사용할 수 있기 때문입니다.

    open class Animal {
    	open func bark() {
    		print("으르렁 으르렁")
    	}
    }
    
    class Dog: Animal {
    	override open func bark() {
    		print("멍멍")
    	}
    }

     

     

    2️⃣ public

    - public 접근 제어자는 기본적으로 open과 접근 제어 정도가 같지만 다른 모듈에서 서브클래싱 하거나 오버라이딩은 할 수 없다.

    public class Animal{
    	public func bark() {
    		print("으러렁 으르렁")
    	}
    }
    
    // 다른 모듈에서 작성한 코드라면 재정의 불가능
    public class Dog: Animal {
    	override public func bark() { // Error
    		print("멍멍")
    	}
    }

     

     

    3️⃣ Internal

    - internal 접근 제어자는 같은 모듈 내에서는 어디서든지 해당 요소들을 사용할 수 있다. 그러나 모듈 외부에서는 사용 할 수 없다.

    internal class Cat: Animal {
    	override internal func bark() {
    		print("야옹")
    	}
    }
    
    // 외부 모듈
    let cat: Cat = Cat() // Error

     

     

    4️⃣ fileprivate

    - fileprivate 접근 제어자는 같은 파일 내에서만 해당 요소들을 사용할 수 있다.

    fileprivate class Dog {
    	fileprivate func bark() {
    		print("멍멍")
    	}
    }
    
    fileprivate let dog = Dog() // 다른 소스 파일이라면 Error
    dog.bark()

     

     

    5️⃣ private

    - private 접근 제어자는 해당 요소가 선언된 블록 내에서만 사용할 수 있다.

    class Company {
    	private let developer = Developer()
    	
    	func writeCode() {
    		developer.writeCode()
    	}
    }
    
    let company: Company = Company()
    company.developer.? // 접근 불가능 Error

     

    🧹 정리

    open - 다른 모듈에서도 접근가능 / 상속 및 재정의도 가능 (제한 낮음)
    public - 다른 모듈에서도 접근가능(상속/재정의불가)
    internal - 같은 모듈 내에서만 접근가능(디폴트)
    fileprivate - 같은 파일 내에서만 접근가능
    private - 같은 scope 내에서만 접근가능 (제한 높음)
    모듈(module) - 프레임워크, 라이브러리, 앱 등 import 해서 사용할 수 있는 외부의 코드

     


     

    커스텀 타입의 접근제어

    - 사용자 정의 타입의 접근제어

     

    1) 타입의 내부 멤버는 타입자체의 접근 수준을 넘을 수 없다.

    internal class SomeClas {
    	open var someOpen = "open"
    	public var somePublic = "public"
    	var some = "internal"
    	fileprivate var someFile = "fileprivate"
    	private var somePublic = "private"
    }

     

    2) 내무 멤버가 명시적 선언을 하지 않는다면, 접근 수준은 internal로 유지

    open class SomeClass {
    	var someProperty = "SomeInternal"
    }
    
    * internal 이다 => 클래스와 동일한 수준을 유지하려면 명시적으로 open 선언이 필요

     


     

    상속과 확장의 접근제어

    상속 관계 주의점 ⛔️

    (1) 상속해서 만든 하위클래스는 상위클래스 보다 더 높은 접근 수준 설정이 되지 않는다.

    (2) 동일 모듈에서 정의한 클래스의 상위멤버에 접근 가능하면, (접근 수준을 올려서) 재정의 가능하다.

    public class A {...}    // 상위클래스
    
    internal class B: A (o) // 하위클래스
    open class B: A (x)     // 하위클래스의 접근수준이 더 높아지는 경우

     

    확장(Extension)의 접근 제어

    - 본체의 멤버에는 기본적인 접근이 가능하다

    public class SomeClas{
    	private var somePrivateDo = "somePrivate"	
    }
    
    extension SomeClass{ // public으로 선언한 것과 같다
    	func somePrivateFunc() { 
    			somePrivateDo = "접근가능" 
    	}
    }

     

     

    속성과 접근 제어

    - 읽기와 쓰기의 접근을 구분 지어 사용하면 편리 ⭐️
    1) 읽기만 접근 private(set)
    2) 쓰기는 접근 불가
    struct TrackString {
    	internal private(set) var numberOfEdits = 0
    
    	var value: String = "시작" {
    		didSet {
    				numberOfEdits += 1
    		}
    	}
    }
    
    var stringToEdit = TrackString()
    
    // * 외부에서 직접 설정하는 것은 불가능 private(set) 설정했기 때문에 (읽기는 가능)
    stringToEdit.numverOfEdits = 3 // Error

     

    댓글