Swift - 11.1 - 协议
2022-03-18 本文已影响0人
aven_kang
协议 - Protoclo
协议可以用来定义方法、属性、下标的声明,协议可以被枚举、结构体、类遵守(多个协议之间用逗号隔开)
protocol Drawable {
func draw()
var x:Int {get set}
var y:Int {get}
subscript(index i:Int) -> Int {get set}
}
protocol Drawable2 {
func draw()
var x:Int {get set}
var y:Int {get}
subscript(index i:Int) -> Int {get set}
}
class ViewController: UIViewController,Drawable {
func draw() {
}
var x: Int = 0
var y: Int = 0
subscript(index i: Int) -> Int {
get {
return i
}
set {
}
}
}
协议中定义方法时,不能有默认参数值
默认情况下,协议中定义的内容必须全部实现
为了保证通用性,协议中必须使用static定义类型方法、类型属性、类型下标
protocol Drawable {
static func draw()
}
因为class只能用在类里面,而协议是可以被结构体和枚举遵守的
所以为了保证通用性,需要加上static,这样大家都能用
mutating
1.只有将协议中的实例方法标记为mutating,才允许结构体、枚举的具体实现修改自身内存
2.类在实现方法时,不用加mutating,枚举、结构体菜需要加mutating
protocol Drawable {
var x:Int {get set}
mutating func draw()
}
struct test : Drawable {
var x:Int = 0
mutating func draw() { //加了mutating才允许这样修改x,否则会报错
x = 10
}
}
class test2 : Drawable {
var x:Int = 0
func draw(){ //类可以直接修改
x = 10
}
}
init
1.协议中还可以定义初始化器init,非final类实现时必须加上required
protocol testP {
init(x:Int, y:Int)
}
class Point : testP {
required init(x: Int, y: Int) {
}
}
final class Point2 :testP {
init(x: Int, y: Int) {
}
}
为什么被final修饰的类,不需要加上required,因为final类型的就说明了,这个类是不能被继承的,就可以防止子类在继承的时候,丢了这个初始化操作,保证了安全
截屏2022-02-23 下午1.20.36.png协议中的init、init?、init!
截屏2022-02-23 下午1.32.51.png协议的继承
protocol Runnable {
func run()
}
protocol Liveable : Runnable {
func breath()
}
class manger : Liveable {
func run() {
}
func breath() {
}
}
协议组合
protocol Runnable {
func run()
}
protocol Liveable : Runnable {
func breath()
}
class manger : Liveable {
func run() {
}
func breath() {
}
}
// 接收Person或者其子类的实例
func fn0(obj:manger) {}
// 接受遵守Liveable协议的实例
func fn1(obj:Liveable) {}
// 接收同时遵守Liveable、Runnable协议的实例
func fn2(obj: Liveable & Runnable) {}
//接收同时遵守Liveable、Runnable协议、并且是Person或者其子类的实例
func fn2(obj: manger & Liveable & Runnable) {}
typealias RealPerson = manger & Liveable & Runnable
//接收同时遵守Liveable、Runnable协议、并且是Person或者其子类的实例
func fn4(obj: RealPerson) {}
CaseIterable
让枚举遵守CaseIterable协议,可以实现遍历
截屏2022-02-23 下午1.54.12.pngCustomStringConvertible
遵守这个协议,相当于OC的description会重置这个类的打印方法
class Person : CustomStringConvertible {
var age:Int = 0
var name:String = "jack"
var description: String {
return "age=\(age),name\(name)"
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
var p1 = Person()
print(p1)
}
}
打印台会打印
age=0,namejack