Swift笔记-协议

146 阅读2分钟

协议

  • 协议可以用来定义方法、属性、下标的声明
  • 协议可以被枚举、结构体、类遵守
  • 协议中定义方法时不能有默认参数值

协议中的属性

  • 协议中定义属性时必须用var关键字
  • 实现协议时的属性权限要不小于协议中定义的属性权限
    • 协议定义get、set,要用var存储属性或get、set计算属性实现
    • 协议定义get,用任何属性实现都可以

协议中的类型方法、类型属性、类型下标

  • 为了保证通用,必须定义为static

mutating

  • 只有将协议中的实例方法标记为mutating,才允许结构体、枚举的具体实现修改自身内存

协议定义init

  • 非final类实现时需要加required
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 {
//可以替换required override 顺序
//    required override init(age: Int) { }
    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) { }
}

//接收Person或者子类实例
func fn0(obj: Person) { }
//接收遵守Livable协议的实例
func fn1(obj: Livable) { }
//接收同时遵守Livable、Runnable协议的实例
func fn2(obj: Livable & Runnable) { }
//接收同时遵守Livable、Runnable协议且是Person或者子类的实例
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) //age is 10

Any 和 AnyObject

  • Any可以代表任意类型(枚举、结构体、类,也包括函数类型)
  • AnyObject表示任意类类型(在协议后面写上AnyObject代表只有类能遵守这个协议)

Self

  • 一般用作返回值类型,限定返回值和方法调用者必须是同一类型