目录
- 版本
- 协议
- 属性要求
- 方法要求
- 构造器要求
- 委托
版本
Xcode 11.3.1
Swift 5.1.3
协议
协议规定了用来实现某一特定功能所必需的方法和属性。
类,结构体或枚举类型都可以遵循协议,并提供具体实现来完成协议定义的方法和功能。
语法
protocol SomeProtocol {
// 这里是协议的定义部分
}
让自定义类型遵循多个协议:
struct SomeStructure: FirstProtocol, AnotherProtocol {
// 这里是结构体的定义部分
}
若是一个类拥有父类,应该将父类名放在遵循的协议名之前,以逗号分隔:
class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol {
// 这里是类的定义部分
}
属性要求
协议不指定属性是存储属性还是计算属性,它只指定属性的名称和类型。
此外,协议还指定属性是可读的还是可读可写的。
如果协议规定可读可写,那么协议的实现也是可读可写的;如果协议规定可读,实现除了可读外,也可根据实际需要是否可写。
在类型声明后加上 { set get } 来表示属性是可读可写的,用 { get } 来表示只读。
protocol Subject {
var name: String { get }
var score: Int { get set }
}
struct Math: Subject {
var name: String { return "Math" }
var score = 0
}
var math = Math()
//math.name = "Chinese" // 只读属性,报错
math.score = 100
print(math.name, math.score)
// 打印 Math 100
方法要求
协议可以要求遵循协议的类型实现某些指定的实例方法或类方法。
protocol SayHello {
func sayHello()
}
class Person: SayHello {
var name: String
init(name: String) {
self.name = name
}
func sayHello() {
print("\(self.name) say hello")
}
}
let xiaoming = Person(name: "小明")
xiaoming.sayHello()
// 小明 say hello
let xiaohong = Person(name: "小红")
xiaohong.sayHello()
// 小红 say hello
构造器要求
你可以在遵循协议的类中实现构造器,无论是作为指定构造器还是作为便利构造器,你都必须为构造器实现标上 required 修饰符:
protocol SayHello {
func sayHello()
}
class Person: SayHello {
var name: String
init(name: String) {
self.name = name
}
func sayHello() {
print("\(self.name) say hello")
}
}
let xiaoming = Person(name: "小明")
xiaoming.sayHello()
// 小明 say hello
let xiaohong = Person(name: "小红")
xiaohong.sayHello()
// 小红 say hello
protocol StudentName {
init(studentName: String)
}
class Student: Person, StudentName {
required init(studentName: String) {
super.init(name: studentName)
}
}
let xiaojun = Student(studentName: "学生小军")
xiaojun.sayHello()
// 学生小军 say hello
委托
委托是一种设计模式,它允许类或结构体将一些需要它们负责的功能委托给其他类型的实例。
举个例子:
// 定义一个看门的协议
protocol WatchDoor {
func watchDoor()
}
// 人类会看门,所以遵循 WatchDoor 协议
class People: WatchDoor {
var name: String
init(name: String) {
self.name = name
}
func watchDoor() {
print("\(self.name)看门")
}
// 定义一个被委托对象,来代理看门任务 (现在这个被委托对象是谁还不知道)
var delegate: WatchDoor? = nil
}
// 打南面来了一条狗
class Dog {
var name: String
init(name: String) {
self.name = name
}
}
// 某天这狗的任督二脉被打通,从此具备看门的能力
extension Dog: WatchDoor {
func watchDoor() {
print("\(self.name)看门")
}
}
// 本来是人类小康看门
let people = People(name: "小康")
people.watchDoor()
// 看到狗儿旺财来了
let dog = Dog(name: "旺财")
// 然后委托旺财来看门
people.delegate = dog
// 现在是旺财在看门
people.delegate?.watchDoor()
/**
小康看门
旺财看门
*/
网友评论