Access Control
Part of the Object Oriented Programming section of Coddy's Swift journey. Lesson 17 of 57.
Encapsulation means a type controls how its data can be used. Access control decides who can see a property or method. Marking a member private hides it from all code outside the type (and its extensions in the same file):
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' is inaccessible due to 'private' protection levelOutside code can then only use what the type offers. The type can check every change, so its data never ends up in a state the type does not allow:
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())Output:
balance: 50Swift has five access levels. Without a keyword a member is internal: visible everywhere in the same module (your app or package). The levels from most open to most restricted:
open // other modules can use and subclass it (classes only)
public // other modules can use it
internal // default: the whole module
fileprivate // this source file only
private // this type (and its extensions in the file)Private helper methods keep the public surface small: callers see what the type does, not how it does it.
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)Output:
true
falseChallenge
EasyComplete the struct Locker. Its code and items are private. store(_:code:) adds an item only when the code matches and returns whether it did; items(code:) returns the stored items joined with , (or empty) when the code matches, and wrong code otherwise.
The supplied code reads the locker's code and then commands put <code> <item> or open <code>. It prints stored or denied for each put, and the result for each open.
Your code goes in Locker.swift. main.swift holds the supplied input/output code and cannot be edited.
Try it yourself
// Supplied input/output code: keep it as it is
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]))
}
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Classes and Objects
Working With FilesDefining ClassesMethods and selfInitializersClasses Are ReferencesRecap - Library Card4Encapsulation
Access ControlRead-Only From OutsideGuarding StateFailable InitializersRecap - Bank Account7Polymorphism and Generics
PolymorphismType CastingGeneric FunctionsGeneric TypesRecap - Shape Calculator5Inheritance
SubclassesOverriding MethodsInitializers and superfinal and HierarchiesRecap - Employee Hierarchy11Project: Library Management
Books and MembersBorrowing BooksPractice on your own: Swift playground