Swift中的协议、元类型、Error异常处理

2021-02-05  本文已影响0人  a_只羊

协议

    class Person: Drawable {
        required init(x: Int, y: Int) {
            self.x = x
            self.y = y
        }
        
        var x: Int = 0
        var y: Int = 0
        
        func draw() {
            print("person draw")
        }
        
        subscript(index: Int) -> Int {
            get {index}
            set {}
        }
        
        static func cDraw() {
            print("协议中定义的类型方法")
        }
        
    }
    class Person2: Drawable {
        
        func draw() {}
        
        var x: Int = 0
        var y: Int = 0
        
        required init(x: Int, y: Int) {
            self.x = x
            self.y = y
        }
        
        subscript(index: Int) -> Int {
            get {
                index
            }
            set {}
        }
        
        //改成class之后能够被子类继承
        class func cDraw() {
            print("我改了协议中定义的类型方法为可继承")
        }
        
    }
    
    class Son: Person2 {
        override class func cDraw() {
            super.cDraw()
            print("子类重写父类方法")
        }
    }
    struct Point: Drawable {
        mutating func draw() {
            self.x = 20
            print("结构体来实现画画")
        }
        
        var x: Int = 0
        var y: Int = 0
        
        subscript(index: Int) -> Int {
            get {index}
            set {}
        }
        
        static func cDraw() {
            print("结构体类型方法")
        }

    }
    
    class Person3 {
        
        var x: Int = 0
        var y: Int = 0
        
        required init(x: Int, y: Int) {
            self.x = x
            self.y = y
            print("来自 Person3")
        }
    }
    class SonTwo: Person3, Drawable {
        
        func draw() {}
                
        subscript(index: Int) -> Int {
            get {index}
            set {}
        }
        
        required init(x: Int, y: Int) {
            super.init(x: x, y: y)
        }
        
        static func cDraw() {}
    }
    class Person4: Livable {
//        required init() {}
        required init!(){}
        
//        required init?(age: Int) {}
//        required init!(age: Int) {}
        required init(age: Int) {}
        
//        required init!(no: Int) {}
        required init?(no: Int) {}
    }
  1. 一个协议可以继承其他协议
  2. 可以通过 & 组合多个类型的协议
  3. 协议组合,可以包含1个类类型(最多一个)
  4. 可以使用扩展 extension 来扩展协议的默认实现
protocol Drawable {
    mutating func draw()
    var x: Int{get set}
    var y: Int{get}
    subscript(index: Int) -> Int {set get}
    init(x: Int, y: Int)
    
    static func cDraw()
}

protocol Livable {
    init()
    init?(age: Int)
    init!(no: Int)
}

extension Drawable {
    mutating func draw(){
        print("扩展默认实现draw方法")
    }
    subscript(index: Int) -> Int {
        set {  }
        get { index }
    }
    
    static func cDraw(){
        print("扩展默认实现cDraw方法")
    }
}
protocol InterProtocol: Drawable {
    func endDraw()
}

class protocolUseDemo {

   //接收Person及其子类的实例
    func fn0(obj: Person){}
    
    //接收遵守Livable协议的实例
    func fn1(obj: Livable) {}

    //接收同时遵守Livable、InterProtocol 协议的实例
    func fn2(obj: Livable & InterProtocol) {}
    
    //接收同时遵守Livable、InterProtocol、Drawable 协议的实例
    func fn3(obj: Livable & InterProtocol & Drawable) {}

}
   
    class CustomStringDescription: CustomStringConvertible {
        var description: String{
            "实现自定义描述内容"
        }
    }
    
    enum Season: CaseIterable {
        case spring, summer, autumn, winter
    }
    
    //遍历season
    func testTravelSeason() {
        let seasons = Season.allCases
        print(seasons.count)
        for season in seasons {
            print(season)
        }
    }

元组
    func testAny() {
        var stu: Any = 10
        stu = "Jack"
        stu = Person(x: 10, y: 20)
        
        //创建一个能够存放任意类型的数组
        var data = [Any]()
        data.append(10)
        data.append(3.15)
        data.append(Person(x: 10, y: 20))
        data.append("Jack")
        data.append({10})
    }
    func testAs() {
        var student: Any = 10
        (student as? Person)?.draw() //没有调用draw方法
        
        student = Person(x: 10, y: 20)
        (student as? Person)?.draw() //调用方法
        (student as! Person).draw() //调用方法
        
        var protocolInstance = student as? Drawable
        protocolInstance?.draw() //调用方法
        
        //以下会报错
//        (student as? Drawable)?.draw()
    }
    func testTypeUse() {
        class Person{}
        class Student: Person{}
        var perType: Person.Type = Person.self
        var student: Student.Type = Student.self
        perType = Student.self
        
        var anyType: AnyObject.Type = Person.self
        anyType = Student.self
        
        typealias AnyClass = AnyObject.Type
        var anyType2: AnyClass = Person.self
        anyType2 = Student.self
        
        
        var per = Person()
        var perTypeTwo = type(of: per) // Person.self
        print(Person.self == type(of: per)) // true
        
    }
    func typeSelfUse() {
        class Animal { required init() { } }
        class Cat: Animal { }
        class Dog: Animal { }
        class Pig: Animal { }
        
        func create(_ clses: [Animal.Type]) -> [Animal]{
            var arrar = [Animal]()
            for cls in clses {
                arrar.append(cls.init())
            }
            return arrar
        }
    }
    func testSelfUse() {
        
        class Person: Runnable{
            func test() -> Self { type(of: self).init() }
            required init() { }
        }
        
        class Student: Person { }
        
        var p = Person()
        print(p.test())
        
        var stu = Student()
        print(stu.test())
    }

Error异常处理

    enum SomeError: Error {
        case illegalArg(String)
        case outOfBounds(Int, Int)
        case outOfMemory
    }
    
    func divide(sourceNum: Int, divideNum: Int) throws -> Int {
        if divideNum == 0 {
            throw SomeError.illegalArg("非法字符")
        }
        
        return sourceNum/divideNum
    }
    
    func testError() {
        do{
            print(try divide(sourceNum: 10, divideNum: 0))
        }catch{
            switch error as? SomeError {
            case let .illegalArg(msg):print(msg)
            case let .outOfBounds(index, end):print("index: \(index) end:\(end)")
            case .outOfMemory:print("内存溢出")
            case .none: print("none error")
            }
        }
         
    }
上一篇 下一篇

猜你喜欢

热点阅读