Swift协议基础
协议规定了实现某些功能的方法、属性。类、结构体或枚举都可以遵循协议,并提供协议的具体实现。
语法
定义方式:
1 | protocal SomeProtocol{ |
自定义类型遵循某个协议:
1 | struct SomeStructure: FirstProtocol, AnotherProtocol{ |
拥有父类的类在遵循协议:
1 | class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol { |
属性要求
协议可以要求遵循协议的类型提供特定名称和类型的实例属性或类型属性。
协议不指定属性是存储型属性还是计算型属性,只指定属性的名称和类型以及属性的可读性可写性。
协议指定的属性可读可写,则属性不能是常量属性或只读的计算型属性。
如果协议只要求属性可读,则该属性可以是可读的,也可以是可读可写的。
协议总是用
var
来声明变量属性,在类型声明后加{set get}
或{get}
来表示属性可读可写或可读:1
2
3
4protocol SomeProtocol {
var mustBeSettable: Int { get set }
var doesNotNeedToBeSettable: Int { get }
}类型属性总是用
static
前缀,如果是类还可以用class
1
2
3protocol AnotherProtocol{
static var someTypeProperty: Int{ get set }
}
方法要求
遵循协议的类型需要实现协议里指定的实例方法或类方法。
协议中的方法可以有可变参数,但参数不能有默认值。
1
2
3
4protocol SomeProtocol{
static func someTypeMethod()
func random() -> Double
}
mutating方法要求
在值类型实例方法中要修改该类型的属性,需要在该方法前加mutating
前缀。
在协议中定义的实例方法,如果方法会改变遵循该协议的类型的实例,需要在方法前mutating
关键字。
实现协议中的 mutating
方法时,若是类类型,则不用写 mutating
关键字。而对于结构体和枚举,则必须写 mutating
关键字。
示例:
1 | protocol Togglable{ |
构造器要求
协议可以要求遵循协议的类型实现指定的构造器。协议里指定构造器:
1 | protocol SomeProtocol{ |
在遵循协议的类中实现构造器,必须在构造器前加required
修饰符:
1 | class SomeClass: SomeProtocol { |
使用 required
修饰符可以确保所有子类也必须提供此构造器实现,从而也能符合协议。如果类已经被标记为 final
,那么不需要在协议构造器的实现中使用 required
修饰符,因为 final
类不能有子类。
如果一个子类重写了父类的指定构造器,并且该构造器满足了某个协议的要求,那么该构造器的实现需要同时标注 required
和 override
修饰符:
1 | protocol SomeProtocol { |
可失败的构造器:
遵循协议的类型可以通过可失败构造器(init?
)或非可失败构造器(init
)来满足协议中定义的可失败构造器要求。协议中定义的非可失败构造器要求可以通过非可失败构造器(init
)或隐式解包可失败构造器(init!
)来满足。