Swift5.1 - 协议(10)

协议(Protocol)

  • 使用 protocol 关键字来定义一个协议;
  • 协议可以用来定义方法属性下标声明
  • 协议可以被枚举结构体遵守;
  • 多个协议之间可以用逗号隔开;
protocol Behaviour {
    func run()
    var age: Int { set get }
    var height: Int {get}
    subscript(index: Int) -> Int { get set}
}
protocol Behaviour1 {}
protocol Behaviour2 {}
protocol Behaviour3 {}

class Animal: Behaviour1, Behaviour2, Behaviour3 {
    
}
  • 协议中定义的方法不能有默认参数值
  • 协议中定义的内容,默认必须全部实现;

协议的属性

  • 协议中定义的属性必须都为 var 属性,let 属性将会报错;
  • 实现协议的属性权限,不小于协议中定义的属性权限;
    1. 如果定义了 get 属性,实现协议时,可以实现为 getget & set的计算属性;
    2. 如果定义了 get & set 属性,那么只能实现为get & set 的计算属性;

static 、class

  • 为了保证通用,协议中必须用static定义类型方法、类型属性、类型下标;
    1. 因为枚举和结构体不能用 class
protocol Behaviour {
    static var height: Int {get}
}

class Animal: Behaviour {
    class var height: Int {
        return 10
    }
}

mutating

  • 只有将协议中的 实例方法 标记为mutating
    1. 才能允许结构体、枚举的具体实现修改自身的内存
    2. 类在实现方法时不用加 mutating 关键字,枚举、结构体需要加mutating(swift5.1好像已经不用加了);
protocol Behaviour {
    mutating func run()
}

struct Animal: Behaviour {
    func run() {
        
    }
}

init

  • 协议还可以声明初始化方法 init;非 final 类实现该初始化器必须加 require 关键字,final 类实现该初始化器可以不加 require 关键字;
protocol Behaviour {
    init(age: Int, name: String)
}

class Animal: Behaviour {
    required init(age: Int, name: String) {
        // ...
    }
}

final class Person: Behaviour {
    init(age: Int, name: String) {
        // ...
    }
}
  • 假如实现的协议方法的初始化器,正是重写父类的指定初始化器,那么这个初始化器方法必须同时加 requireoverride 关键字;
  • 协议中定义的 init?init!,可以用 initinit?init! 去实现;
  • 协议中定义的 init,可以用 initinit! 去实现;

协议的继承

  • 一个协议可以继承其他协议的方法,属性,下标;
protocol Behaviour {
    func run()
    subscript(index: Int) -> Int {get}
}

protocol SubBehaviour: Behaviour {
    func eat()
}

class Animal: SubBehaviour {
    subscript(index: Int) -> Int {
        return 10
    }
    
    func eat() {
        //...
    }
    
    func run() {
        //...
    }
}

协议的组合

  • 协议组合可以包含最多1个类类型;
protocol Drawable {}
protocol Runnable {}
class Person {}

// 接收Person或其子类的实例
func test1(obj: Person) {}

// 接收遵守Drawable协议的实例
func test2(obj: Drawable) {}

// 接收遵守 Drawable与Runnable 协议的实例
func test3(obj: Drawable & Runnable) {}

// 接收遵守 Drawable与Runnable 协议,并且是Person或其子类的实例
func test4(obj: Person & Drawable & Runnable) {}

CaseIterable

  • 让枚举遵守 CaseIterable 协议,可以实现枚举遍历;
enum Test : CaseIterable {
    case a, b, c, d
}

let cases = Test.allCases
print(cases.count)  // 4
for c in cases {
    print(c)
}  // a、b、c、d

你可能感兴趣的:(Swift5.1 - 协议(10))