美文网首页swift学习
Swift5.1 - 协议(10)

Swift5.1 - 协议(10)

作者: HChase | 来源:发表于2019-07-31 09:21 被阅读18次

    协议(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)

        本文链接:https://www.haomeiwen.com/subject/gysorctx.html