Swift5.1学习随笔之协议Protocol

2020-04-30  本文已影响0人  SAW_

协议Protocol

protocol Drawable {
    func draw()
    var x: Int { get set }
    var y: Int { get }
    subscript(index: Int) -> Int { get set }
}
protocol Test1 {}
protocol Test2 {}
protocol Test3 {}
class TestClass: Test1, Test2, Test3 { }
class Personal: Drawable {
    var x: Int = 0
    var y: Int = 0
    func draw() {
        print("Personal draw")
    }
    subscript(index: Int) -> Int {
        get { index }
        set { }
    }
}

协议中的属性

protocol Drawable {
    var x: Int { get set }
    var y: Int { get }
}

协议Drawable中定义了两个变量xy,那么在其他对象中如何实现这两个属性,如果做到实现的时候让x是可读可写的,让y是只读的

class Personal: Drawable {
    var x: Int = 0
    let y: Int = 0
}
class Personal: Drawable {
    var x: Int {
        get { 0 }
        set { }
    }
    var y: Int {
        get { 0 }
    }
}

static、class

protocol Drawable {
    static func draw()
}
//如果允许子类重写,就用class
class Personal: Drawable {
    class func draw() {
        print("Personal draw")
    }
}
//如果不允许子类重写,就用static
class Personal: Drawable {
    static func draw() {
        print("Personal draw")
    }
}

mutating

只有将协议中的实例方法标记为mutating

protocol Drawable {
    mutating func draw()
}

class Size: Drawable {
    var width: Int = 0
    func draw() {
        width = 10
    }
}

struct Point: Drawable {
    var x: Int = 0
    mutating func draw() {
        x = 10
    }
}

init

协议中还可以定义初始化器init

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) { }
}

如果从协议实现的初始化器,刚好是重写了父类的指定初始化器

protocol Livable {
    init(age: Int)
}

class Person {
    init(age: Int) { }
}

class Student: Person, Livable {
    required override init(age: Int) {
        super.init(age: age)
    }
}

init、init?、init!

protocol Readable {
    init()
    init?(age: Int)
    init!(num: Int)
}

class Personal: Readable {
    required init() { }
//    required init!() { }
    
    required init?(age: Int) { }
//    required init!(age: Int) { }
//    required init(age: Int) { }
    
    required init!(num: Int) { }
//    required init?(num: Int) { }
//    required init(num: Int) { }
}

协议的继承

一个协议可以继承其他协议

protocol Runnable {
    func run()
}

protocol Livable: Runnable {
    func breath()
}

class Person: Livable {
    func run() {}
    func breath() {}
}

协议组合

协议组合,可以包含1个类类型(最多一个)

protocol Livable { }
protocol Runnable { }
class Personal { }

//接受Personal或者其子类的实例
func fn1(obj: Personal) { }
//接受遵守Livable协议的实例
func fn2(obj: Livable) { }
//接受同时遵守Runnable、Livable协议的实例
func fn3(obj: Livable & Runnable) { }
//接受同时遵守Runnable、Livable协议,并且是Personal或者其子类的实例
func fn4(obj: Personal & Livable & Runnable) { }
typealias RealPerson = Personal & Livable & Runnable
//接受同时遵守Runnable、Livable协议,并且是Personal或者其子类的实例
func fn(obj: RealPerson) { }

CaseInterable

让枚举遵守CaseInterable协议,可以实现遍历枚举值

enum Season: CaseIterable {
    case spring, summer, autumn, winter
}
let seasons = Season.allCases

print(seasons) // [SwiftDDDDD.Season.spring, SwiftDDDDD.Season.summer, SwiftDDDDD.Season.autumn, SwiftDDDDD.Season.winter]

for season in seasons {
    print(season)
} // spring summer autumn winter

CustomStringConvertible

遵守CustomStringConvertible协议,可以自定义实例的打印字符串
必须实现

var description: String 
class Car: CustomStringConvertible {
    var name: String
    var price: Double
    init(name: String, price: Double) {
        self.name = name
        self.price = price
    }
    var description: String {
        "name = \(name), price = \(price)"
    }
}

var c = Car(name: "三轮车", price: 100.1)
print(c) // name = 三轮车, price = 100.1

Any、AnyObject

swift提供了2种特殊的类型:AnyAnyObject

举例子🌰1

protocol Runnable { }

class Personal: Runnable { }

struct Size: Runnable {}
protocol Runnable: AnyObject { }

class Personal: Runnable { }

//报错:Non-class type 'Size' cannot conform to class protocol 'Runnable'
struct Size: Runnable {}

举例子🌰2

var stu: Any = 10
stu = "jack"
stu = Student()
var stu: AnyObject = 10 //报错:Value of type 'Int' does not conform to specified type 'AnyObject'
stu = "jack" //报错:lue of type 'String' does not conform to 'AnyObject' in assignment
stu = Student()

举个例子🌰3:创建1个能存放任意类型的数组

var data = Array<Any>()
data.append(1)
data.append(3.14)
data.append(Person())
data.append("jack")
data.append({10})
data.append(true)
上一篇 下一篇

猜你喜欢

热点阅读