在design pattern中,interface是一個重要的概念。
它能夠將class之間共通但些許不同的行為提升到更高的層次,解決物件導向裡容易誤用繼承的問題
而Swift提供protocol做為interface和資料型態,讓物件導向設計變得更直觀
Declare
1 | protocol ExampleProtocol { |
protocol的property可宣告為gettable或settable,後者同時也可使用get
而function只需要宣告輸入參數和回傳型態,不需要實作
class一旦使用protocol,就必須提供其property和function的實作。
Usage
使用protocol在實務上有什麼好處呢?
假如我們有二個class,Employee和HourlyEmployee,分別為正職和計時人員。 以及計算員工薪資的function1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26class Employee {
let name: String
let address: String
init(name: String, address: String) {
self.name = name
self.address = address
}
func pay() -> (salary: Double, bonus: Double) {
return (3000, 400)
}
}
class HourlyEmployee: Employ {
var hourlyWage: Double = 15.00
var hoursWorked: Double = 8
override pay() -> (salary: Double, bonus: Double) {
return (hourlyWage * hoursWorked, 0)
}
}
func payEmployee(employee: Employee) {
let paycheck = employee.pay()
}
假如之後程式修改時,不小心將HourlyEmployee的pay刪除,則呼叫payEmployee時會回傳Employee的結果
這在程式碼增長的情況下是很容易出現的bug
使用protocol可減少此類bug的發生1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22protocol Payable {
func pay() -> (salary: Double, bonus: Double)
}
class Employee: Payable {
//略
func pay() -> (salary: Double, bonus: Double) {
return (3000, 400)
}
}
class HourlyEmployee: Payable {
//略
override pay() -> (salary: Double, bonus: Double) {
return (hourlyWage * hoursWorked, 0)
}
}
func payEmployee(employee: Employee) {
let paycheck = employee.pay()
}
假如HourlyEmployee的pay function被刪,complier會提示error。
Types
protocol不只能當interface使用,也能做type結合array、dictionary使用1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24protocol Flyable {
func fly()
}
class Human {
let name: String
}
class Bird: Flyable {
let name: String
func fly() {
print("I believe I can fly!")
}
}
func makeActions(action: [Flyable]) {
}
let human = Human(name: "John")
let sparrow = Bird(name: "GOT")
let animals: [Flyable] = [human, sparrow] // Error, human is not Flyable
指定animals為Flyable的array時,compiler會檢查array的值是否符合
這也類似有經驗的C/C++ programmer會將使用enum當function的參數,否則各參數都是int時,容易讓使用者誤用
protocol能幫我們減少無謂的bug及提高程式碼的可讀性