The final keyword in Swift
The final keyword in Swift
In Swift, we have a final
keyword, which can prevent a class, method, property, or subscript from being overridden.
For example, if we want to prevent a class from being overridden. We can do like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
final class BankAccount {
let accountNumber: String
private(set) var balance: Double
init(accountNumber: String, initialBalance: Double) {
self.accountNumber = accountNumber
self.balance = initialBalance
}
func deposit(amount: Double) {
balance += amount
}
func withdraw(amount: Double) {
if amount <= balance {
balance -= amount
} else {
print("Insufficient account balance")
}
}
}
class SavingAccount: BankAccount { } // Compile-time error
We can also only restrict the specific methods, properties, or subscripts from being overridden.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class ColorPalette {
// A final method that returns the hexadecimal color code for a given color name.
final func hexColor(for name: String) -> String {
let colorDict = [
"red": "#FF0000",
"green": "#00FF00",
"blue": "#0000FF",
]
return colorDict[name] ?? defaultColor
}
// A final computed property that returns the default color (white).
final var defaultColor: String {
return "#FFFFFF"
}
// A final subscript that returns a color name from a predefined list based on the index.
final subscript(index: Int) -> String {
let colors = ["red", "green", "blue", "yellow", "purple"]
if index >= 0 && index < colors.count {
return colors[index]
} else {
return "unknown"
}
}
// A non-final computed property that can be overriden.
var favoriteColor: String {
return "red"
}
}
let palette = ColorPalette()
print("Hex for red: \(palette.hexColor(for: "red"))") // Expected Output: "#FF0000"
print("Default color: \(palette.defaultColor)") // Expected Output: "#FFFFFF"
print("Color at index 2: \(palette[2])") // Expected Output: "blue"
print("Color at index 5: \(palette[5])") // Expected Output: "unknown"
class CustomColorPalette: ColorPalette {
override func hexColor(for name: String) -> String { ... } // Compile-time error
override var defaultColor: String { ... } // Compile-time error
override subscript(index: Int) -> String { ... } // Compile-time error
// Okay
override var favoriteColor: String {
return "green"
}
}
Methods, properties, or subscripts that you add to a class extension can also be marked as final
to prevent from being overridden.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Vehicle {
let make: String
let model: String
init(make: String, model: String) {
self.make = make
self.model = model
}
}
extension Vehicle {
@objc var fullDescription: String {
"\(make) \(model)"
}
@objc final func honk() {
print("Honk! Honk! - \(fullDescription)")
}
}
class Car: Vehicle {
// Okay
override var fullDescription: String {
return "Car: \(make) \(model)"
}
// Compile-time error
override func honk() {
print("Beep beep!")
}
}
References
This post is licensed under CC BY 4.0 by the author.