접근 제어(Access Controls)

썹스·2022년 12월 7일
0

Swift 문법

목록 보기
48/68

접근 제어(Access Controls)

접근 제어(Access Controls), 접근 수정자(Access Modifiers), 접근 지정자(Access Specifiers)는 모두 같은 의미로 사용되고 있으며, Swift에서는 "접근 제어(Access Controls)"라는 말을 주로 사용합니다.

  • 접근 제어는 Swift의 엔티티(Entity), 독립된 개체에서만 사용할 수 있습니다.
    여기서 엔티티(Entity)와 독립된 개체는 아래와 같습니다.
    • 커스텀 타입(클래스, 구조체, 열거형)
    • 스위프트의 기본 타입(Int, String, Double 등)
    • 변수, 속성
    • 함수, 메서드(생성자, 서브스크립트 포함)
    • 프로토콜 등...

(사실 Swift의 대부분 타입은 접근 제어 기능을 사용할 수 있음)


🤔 접근 제어를 왜 사용할까??

코드의 세부적 구현 내용에 접근을 제어하는 기능을 부여하여 외부/내부의 접근을 통제할 수 있습니다. (객체지향의 4대 특징: 은닉화)

이를 통해 코드의 안정성 및 보안성, 사용 의도, 특정 로직 구현 등의 기능을 도출할 수 있습니다.


📌 Swift의 5가지 접근 수준

모듈(module): 프레임워크, 라이브러리, 앱 등 import 해서 사용할 수 있는 외부의 코드를 모듈(module)이라고 부릅니다.


📌 접근 제어의 기본 규칙

특정 접근 제어를 부여받은 타입을 사용하기 위해서는 해당 타입 보다 낮은 수준의 접근 제어가 필요합니다.

✅ 기본 규칙 관련 코드

public class Man{
    var name: String
   
    init(name: String){
        self.name = name
    }
}

// 변수 "kim"의 접근 수준은 "Man" 클래스의 접근 수준보다 낮으므로 사용할 수 있습니다.
fileprivate var kim = Man(name: "김철수")

// 변수 "shin"의 접근 수준은 "Man" 클래스의 접근 수준보다 높으므로 사용할 수 없습니다.
open var shin = Man(name: "신짱구")  // 에러 발생

📌 실무에서 사용하는 암묵적/관습적인 패턴

실제 실무에서 많이 사용하는 패턴 방식은 "private 접근 제어"가 적용된 변수(속성...)에 암묵적/관습적으로 언더바( _ )를 사용하여 이름을 짓는 방식입니다.

✅ 언더바( _ )를 사용한 패턴 예시

class Name{
    private var _name: String
   
    var name: String{  // 읽기 기능만을 할 수 있는 로직을 생성
        return _name
    }
   
    init(_name: String){
        self._name = _name
    }
}


var kim = Name(_name: "김철수")

//kim._name    // 에러 발생: private로 선언했기 때문에 읽을 수가 없습니다.
kim.name       // 읽기 기능을 사용하고 싶을 때 특별 로직을 사용

Swift에서는 언더바( _ )를 사용한 패턴 방식의 코드 보다 간결하게 코드를 작성할 수 있도록 해주는 문법이 존재합니다.

접근 제어에 괄호를 열어 특정 기능(get, set)만을 지정하는 방식입니다.

✅ 언더바( _ )를 사용한 패턴 방식보다 간결한 코드 예시

class Name{
    private(set) var name: String //읽기(get)는 internal, 쓰기(set)는 private
    // internal private(set) var name: String  // internal는 생략 가능
   
    init(name: String){
        self.name = name
    }
}

var kim = Name(name: "김철수")
kim.name
//kim.name = "신짱구"  // 에러 발생: 쓰기(set) 기능은 private

읽기(get)는 public, 쓰기(set)는 fileprivate으로 구현할 수도 있습니다.

public fileprivate(set) var test: String // 읽기(get)는 public, 쓰기(set)는 fileprivate으로 구현

커스텀 타입(Custom Type)의 접근 제어

커스텀 타입(클래스, 구조체, 열거형)에 접근 제어를 선언하면 해당 커스텀 타입의 멤버는 커스텀 타입의 접근 수준을 넘을 수 없습니다.

또한 내부 멤버에 접근 수준을 명시적으로 선언하지 않으면, 접근 수준은 internal(디폴트 값) 수준으로 유지됩니다.

✅ 커스텀 타입(Custom Type)의 접근 제어

class Man{  // class Man = internal class Man{}
    open var test1: String
    // test1의 접근 제어 선언은 open으로 했지만, 실제 작동은 internal 수준으로 작동합니다.
   
    public var test2: String
    // test2의 접근 제어 선언은 public으로 했지만, 실제 작동은 internal 수준으로 작동합니다.
   
    private var test3: String
    // test3의 접근 수준은 Man 클래스의 접근 수준보다 낮으므로 private 수준으로 작동합니다.
   
    var test4: String
    // 접근 수준을 명시하지 않았기 때문에 디폴트 접근 제어인 internal 수준으로 작동합니다.
   
    init(test1: String, test2: String, test3: String, test4: String){
        self.test1 = test1
        self.test2 = test2
        self.test3 = test3
        self.test4 = test4
    }
}

📌 상속(Inheritance)의 접근 제어

하위(자식) 클래스는 상위(부모) 클래스의 접근 수준을 넘어설 수 없습니다.

하지만 클래스 내부의 멤버는 상위(부모) 클래스의 접근 수준을 넘어설 수 있습니다.

✅ 상속 가능한 경우

// 상위(부모) 클래스 A
open class A{ }

// 하위(자식) 클래스 B
private class B: A{ }  // 자식 클래스의 접근 수준이 낮으므로 상속 가능

✅ 상속 불가능한 경우

// 상위(부모) 클래스 A
private class A{ }

// 하위(자식) 클래스 B
open class B: A{ }     // 자식 클래스의 접근 수준이 높으므로 상속 불가능 

✅ 멤버의 접근 수준

상위(부모) 클래스 내 멤버의 접근 수준을 하위(자식) 클래스에서 높은 수준으로 또는 더 낮은 수준으로 재정의할 수 있습니다.

// 상위(부모) 클래스 A
open class A{
    fileprivate func AAA(){
        print("A 출력")
    }
}

// 하위(자식) 클래스 B
class B: A{
    override public func AAA() {
        print("B에서 A 출력")
    }
}

확장(Extension)의 접근 제어

본체의 내용/기능을 확장하더라도 접근 수준은 변하지 않습니다. (접근 수준은 원래 본체와 같은 수준을 유지)

또한 본체에서 private 수준으로 정의한 멤버는 확장 scope(범위: { })에서도 사용할 수 있습니다.

✅ 확장(Extension)의 접근 제어

open class Man{
    private(set) var name: String
   
    init(name: String){
        self.name = name
    }
}

extension Man{  // 확장을 해도 접근 수준은 open
    func change(nameChange: String){
        name = nameChange
    }
}

var kim = Man(name: "김철수")
kim.change(nameChange: "신짱구")

print(kim.name)  // 신짱구
profile
응애 나 코린이(비트코인X 코딩O)

0개의 댓글