协议可以用来定义方法、属性、下标的声明,协议可以被枚举、结构体、类遵守
protocol Test {}
protocol Test1 {
func run()
}
protocol Test2 {}
class TestClass : Test,Test1,Test2 {
func run() {}
}
一、属性
protocol Test {
var age : Int {set get}
var name : String {get}
var height : Int {set get}
}
class TestClass : Test {
var age: Int {
set {}
get {20}
}
var name: String {
get {""}
}
var height:Int = 20
}
- 1、协议中定义属性时必须用var关键字,通过在后面声明set、get来告诉该属性是可读还是可写。
- 2、协议属性可以通过存储属性或者计算属性来实现。
二、class和static
protocol Test {
static func test()
static var age : Int{set get }
}
class TestClass : Test {
static var age: Int = 20
class func test() {
print("测试")
}
}
- 为了保证通用,协议中必须用static定义类型方法、类型属性、类型下标
三、init
协议中还可以定义初始化器
protocol Test {
init(x:Int, y:Int)
}
final class Student : Test {
init(x: Int, y: Int) {
}
class Person: Test {
required init(x: Int, y: Int) {
}
}
}
- 非final类实现协议的初始化方法时必须加上 required
四、协议的继承
protocol Liveable {
func run()
}
protocol Runalbe :Liveable{}
class Student : Runalbe{
func run() {}
}
一个协议可以继承其它协议
五、协议的组合
协议组合,可以包含1个类类型(最多一个)
protocol Liveable {}
protocol Runalbe{}
class Person : Liveable,Runalbe {}
//接收Person或者其子类的是实例
func fn0(obj:Person){}
//接收遵守Liveable协议的实例
func fn1(obj:Liveable){}
//接收遵守Liveable、Runnable协议的实例
func fn2(obj:Liveable & Runalbe ){}
//接收遵守Liveable、Runnable协议的实例
func fn3(obj:Person & Liveable & Runalbe ){}
六、常用协议
6.1、CaseIterable
让枚举遵守Caseiterable协议,可以实现遍历枚举
enum Season : CaseIterable {
case spring,summer,autumn,winter
}
let seasons = Season.allCases
for season in seasons {
print(season)
}
6.2、 Equatable
对象遵守Equatable协议,可以使对象通过==运算符进行比较
class Student : Equatable {
static func == (lhs: Student, rhs: Student) -> Bool {
return lhs.age == rhs.age
}
var age : Int = 0
var name :String = ""
}
let s1 = Student()
s1.age = 20
s1.name = "jack"
let s2 = Student()
s2.age = 20
s2.name = "john"
if s1 == s2 {
print("我们都一样")
}else{
print("我们不一样")
}