Menu
Coddy logo textTech

접근 제어

Coddy Swift 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 57개 중 17번째.

캡슐화는 타입이 해당 데이터의 사용 방법을 제어하는 것을 의미합니다. 접근 제어는 누가 프로퍼티나 메서드를 볼 수 있는지 결정합니다. 멤버를 private로 표시하면 타입 외부의 모든 코드(및 같은 파일에 있는 해당 타입의 확장)에서 해당 멤버를 숨깁니다:

struct Account {
    private var balance = 0

    mutating func deposit(_ amount: Int) {
        balance += amount
    }
}

var a = Account()
a.deposit(50)
// a.balance = 1_000_000   // error: 'balance'는 'private' 보호 수준으로 인해 접근할 수 없습니다

코드 외부에서는 타입이 제공하는 것만 사용할 수 있습니다. 타입은 모든 변경을 확인할 수 있으므로 해당 타입이 허용하지 않는 상태로 데이터가 절대 남지 않습니다:

struct Account {
    private var balance = 0

    mutating func deposit(_ amount: Int) {
        if amount > 0 { balance += amount }
    }

    func report() -> String {
        "balance: \(balance)"
    }
}

var a = Account()
a.deposit(50)
a.deposit(-999)
print(a.report())

출력:

balance: 50

Swift에는 다섯 가지 접근 수준이 있습니다. 키워드가 없으면 멤버는 internal입니다. 즉, 같은 모듈(앱 또는 패키지) 어디에서나 볼 수 있습니다. 가장 개방적인 수준부터 가장 제한적인 수준까지는 다음과 같습니다.

open        // 다른 모듈에서 사용하고 서브클래스로 만들 수 있음 (클래스만)
public      // 다른 모듈에서 사용할 수 있음
internal    // 기본값: 전체 모듈
fileprivate // 이 소스 파일만
private     // 이 타입 (및 파일 내의 확장)

비공개 헬퍼 메서드는 공개 인터페이스를 작게 유지합니다. 호출자는 타입이 무엇을 하는지는 보지만, 어떻게 하는지는 보지 못합니다.

struct Password {
    private let text: String

    init(_ text: String) { self.text = text }

    var isStrong: Bool {
        hasDigit() && text.count >= 8
    }

    private func hasDigit() -> Bool {
        text.contains { $0.isNumber }
    }
}

print(Password("secret123").isStrong)
print(Password("short1").isStrong)

출력:

true
false
challenge icon

챌린지

쉬움

Locker 구조체를 완성하세요. code와 items는 private입니다. store(_:code:)는 코드가 일치할 때만 항목을 추가하고 추가되었는지를 반환합니다. items(code:)는 코드가 일치하면 저장된 항목을 , 으로 결합한 결과를 반환하며(또는 empty), 일치하지 않으면 wrong code를 반환합니다.

제공된 코드는 보관함의 코드를 읽은 다음 put <code> <item> 또는 open <code> 명령을 처리합니다. 각 put에 대해 stored 또는 denied를 출력하고, 각 open에 대해서는 결과를 출력합니다.

코드는 Locker.swift에 작성하세요. main.swift에는 제공된 입력/출력 코드가 있으며 수정할 수 없습니다.

직접 해보기

// 제공된 입력/출력 코드: 있는 그대로 유지하세요
var input: [String] = []
while let line = readLine() { input.append(line) }
var locker = Locker(code: input[0])
for cmd in input.dropFirst() {
    let p = cmd.split(separator: " ").map(String.init)
    if p[0] == "put" {
        print(locker.store(p[2], code: p[1]) ? "stored" : "denied")
    } else {
        print(locker.items(code: p[1]))
    }
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: Swift 플레이그라운드