「这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战」。
- 本文主要介绍
Swift中的协议的使用
1.协议与继承
我们定义2个类
class Person {
var name = "jack"
}
class Dog {
var name = "十六"
var age = 3
}
在了解协议前我们可以看下下面的场景,我们为这2个类添加一个方法用来打印当前类的信息。我们可以把抽出来继承一个公共的类,公共类有debug的方法,子类可以调用。但是从业务逻辑上来说,这么处理不太合理。可能最直观的办法是对于每一个类都写一个单独的方法。
class Person {
var name = "jack"
func debug(){
print(type(of: self))
}
}
class Dog {
var name = "十六"
var age = 3
func debug(){
print(type(of: self))
}
}
如果我们对当前代码中的每个类都需要 debug ,那上面这种方法显然是行不通的,于是我们有 了下面的代码
func debug(subject:AnyObject){
print(type(of: subject))
}
当然看到这里可能大家也会觉得没有问题,如果我们要具体的描述当前类的具体信息,这个时候 我们还需要引入一个公共的基类,同时我们还需要有一个公共的属性 description 来让子类重 载,这无疑对我们的代码是很强的入侵。
所以这个时候我们通过一个协议来描述当前类的共同行为,并通过 extension 的方式来对我们 的类进行扩展
简单小结下:
class类本质上定义了对象是什么protocol协议则是定义了对象有哪些行为
2. 协议的使用
- 协议的委托 通常类,结构体,枚举都可以遵循协议,如果遵循多个协议则用,隔开
如果类有继承关系的话,放在协议之前
- 协议添加属性
我们在协议中定义属性必须是可读的或者可读可写的,否则报错
protocol MyProtocol {
var age:Int{get}//可读的
var name:String{get set}//可读写的
}
属性必须要是var形容,不能用let
- 协议
添加方法
protocol MyProtocol {
var age:Int{get}//可读的
var name:String{get set}//可读写的
static func test()//类方法
func test1()
func test2() ->Int//带返回值
func test3(_ amount:Int)->Int//带参数
}
//实现
class Person :NSObject,MyProtocol{
func test3(_ amount: Int) -> Int {
return age+amount
}
var age: Int = 0
static func test() {
}
func test1() {
}
func test2() -> Int {
return age
}
var name = "jack"
}
let p = Person()
p.age = 20
p.test1()
print(p.test3(20))
Person.test()
方法中可以添加参数,也可以不添加返回值,也可以添加类方法。和我们在类中定义方法类似,只是不需要实现。如果我们需要某些方法是可选的,因为协议中方法默认是必须要实现的required。
我们只需在协议前@objc修饰,在方法前@objc optional修饰。
定义初始化方法,当实现初始化器时,必须使用required关键字
但是如果我们使用final修饰类的话,表示它不可继承,就不需要使用required修饰了
3. 协议的进阶使用
mutating将协议中的实例方法标记为mutating,才允许结构体、枚举的具体实现修改自身内存。类在实现方法时不用加mutating,枚举、结构体才需要加mutating。
protocol PrintClassInfo {
mutating func debug()
}
class Student: PrintClassInfo {
func debug() {
print("debug")
}
}
struct MyStruct: PrintClassInfo{
mutating func debug() {
print("debug")
}
}
- 协议的继承
协议也可以
继承别的协议,类继承后都可以实现协议的方法
protocol PrintClassInfo {
func debug()
}
protocol PrintClassInfo1:PrintClassInfo {
func printLog()
}
class Student: PrintClassInfo1 {
func printLog() {
}
func debug() {
print("debug")
}
}
专用协议通过添加AnyObject关键字到协议的继承列表,你就可以限制协议只能被类的类型采纳