协议
- 协议可以用来定义方法、属性、下标的声明
- 协议可以被枚举、结构体、类遵守
- 协议中定义方法时不能有默认参数值
协议中的属性
- 协议中定义属性时必须用var关键字
- 实现协议时的属性权限要不小于协议中定义的属性权限
- 协议定义get、set,要用var存储属性或get、set计算属性实现
- 协议定义get,用任何属性实现都可以
协议中的类型方法、类型属性、类型下标
mutating
- 只有将协议中的实例方法标记为mutating,才允许结构体、枚举的具体实现修改自身内存
协议定义init
protocol Drawable {
init(x:Int, y:Int)
}
class Point: Drawable {
required init(x: Int, y: Int) { }
}
final class Size: Drawable {
init(x: Int, y: Int) { }
}
- 如果从协议实现的初始化器,刚好是重写了父类的初始化器,那么这个初始化方法必须加required和override
protocol Livable {
init(age: Int)
}
class Person {
init(age: Int) { }
}
class Student: Person, Livable {
override required init(age: Int) {
super.init(age: age)
}
}
- 协议中定义的init?、init! , 可以用init、init? 、init! 去实现
- 协议中定义的init,可以用init,init! 去实现
协议的继承
协议组合
- 协议组合可以包含一个类类型,组合时不能是结构体类型
protocol Livable {
init(age: Int)
}
protocol Runnable { }
class Person {
init(age: Int) { }
}
func fn0(obj: Person) { }
func fn1(obj: Livable) { }
func fn2(obj: Livable & Runnable) { }
func fn3(obj: Person & Livable & Runnable) { }
CaseIterable
- 让协议遵守CaseIterable,可实现遍历枚举值
enum Season : CaseIterable {
case spring, summer, autumn, winter
}
let seasons = Season.allCases
print(seasons)
for season in seasons {
print(season)
}
CustomStringConvertible
class Person : CustomStringConvertible {
var age: Int
init(age: Int) {
self.age = age
}
var description: String {
"age is \(age)"
}
}
let man = Person.init(age: 10)
print(man)
Any 和 AnyObject
- Any可以代表任意类型(枚举、结构体、类,也包括函数类型)
- AnyObject表示任意类类型(在协议后面写上AnyObject代表只有类能遵守这个协议)
Self
- 一般用作返回值类型,限定返回值和方法调用者必须是同一类型