美文网首页
Swift面向协议基础

Swift面向协议基础

作者: 数字d | 来源:发表于2020-01-21 10:22 被阅读0次
    import UIKit
    
    var str = "Hello, playground"
    
    //协议:方法、属性、或者一个功能的的声明(没有实现)
    
    //协议可以被类,结构体,枚举使用而实现具体的方法
    //任何满足协议需求的类型,被称为尊从该协议
    
    protocol AProtocol {
        
    }
    
    protocol BProtocol {
        
    }
    
    //一个结构体或者类尊从多个协议,用逗号分隔开
    
    struct AStruct : AProtocol,BProtocol {
        
        
    }
    
    class Name {
        
    }
    //超类Name写在协议AProtocol之前,常规操作
    class GivenName : Name ,AProtocol ,BProtocol {
        
        
    }
    
    //结构体和枚举不能继承,但是结构体和枚举能够遵从协议,达到一个继承的目的,而协议的遵从,就类似于只要我遵从的协议的一小块功能。这样灵活一点
    
    //属性协议,用的最多了
    
    //要求实现getter方法(setter可选),属性必须定义为变量
    
    //属性协议
    protocol FileAccessPriority {
        var readOnly : Bool { get }
        var readWrite : Bool {get set}
        
        
    }
    
    
    protocol AccessUrl {
        static var link: String { get }
    }
    
    
    protocol FullName {
        var fName : String {get}
        var gName : String {get}
    }
    
    struct Student : FullName {
        var fName: String
        var gName: String
        
    }
    
    struct Teacher : FullName {
        var fName: String
        var gName: String
    }
    
    var student1 = Student(fName: "小明", gName: "王")
    student1.fName
    student1.gName
    
     class SSomeBody : FullName {
        
        var title:String?
        var name: String
        
        init(title: String?, name:String) {
            self.title = title
            self.name = name
        }
        
        var gName: String {
            return name
        }
        var fName: String {
            return title ?? "无名人士"
        }
        
        var desc : String {
            return self.fName + self.gName
        }
        
        
    }
    
    var sombody1 = SSomeBody(title: "大帝", name: "亚历山大")
    sombody1.gName
    sombody1.fName
    
    var nobody1 = SSomeBody(title: nil, name: "小波")
    nobody1.fName
    nobody1.gName
    
    
    //方法协议
    
    //让类,结构体,枚举分解为更小的组合
    
    //类型方法写协议 前缀总是static
    
    protocol AMethod {
        static func foo()
    }
    
    
    class A :AMethod {
    //    不可被继承
        static func foo() {
            print("aaa aaa ")
        }
    //    可被继承
    //    class func foo() {
    //        print("bbb")
    //    }
    }
    
    
    
    import Foundation
    //实例方法协议
    //产生随机数
    protocol RandomGeneratable {
        func randomNumber() -> Int
    }
    
    struct RandomNumber : RandomGeneratable {
        func randomNumber() -> Int {
            return Int(arc4random())
        }
    }
    
    let random1 = RandomNumber()
    random1.randomNumber()
    
    
    struct RnadomNumberInSix : RandomGeneratable {
        func randomNumber() -> Int {
            return Int(arc4random()) % 6 + 1
        }
    }
    
    let random2 = RnadomNumberInSix()
    random2.randomNumber()
    
    
    
    //结构体,枚举 编译方法协议 需要更改的时候需要添加mutating
    
    
    protocol Switchable {
      mutating func onoff()
    }
    
    enum MySwitch : Switchable {
        case on,off
        mutating func onoff() {
            switch self {
            case .off:
                self = .on
            default:
                self = .off
            }
        }
    }
    
    //构造方法协议
    
    //可以要求遵从者实现指定的构造方法,实现时用required init,编译时候会提示添加,无需手动添加required,不常用
    
    protocol C {
        init(c: Int)
    }
    
    struct D : C {
        init(c: Int) {
            
        }
    }
    
    class E : C {
        required init(c: Int) {
            
        }
        
        
    }
    
    
    //协议作为类型使用***
    //可用于参数类型,返回类型,变量,常量,属性,集合类型中的元素类型
    
    class MyRandomNumber : RandomGeneratable {
        func randomNumber() -> Int {
            return Int(arc4random()) % 10 + 1
        }
    }
    
    struct Dice {
        var sides : Int
        var randomNumber : RandomGeneratable
        
        func play() -> Int {
            return self.randomNumber.randomNumber() % sides + 1
        }
        
    }
    
    let aDice = Dice(sides: 99, randomNumber: RandomNumber())
    
    aDice.play()
    
    
    //协议作为代理使用
    
    //协议作为代理:代理是一种常见的设计模式,可以让类或者结构体把一部分职责,指派给非同类的实例去承担。
    
    //要寻求代理,可以通过定义一个协议,打包要实现的职责在协议中。
    
    //该代理协议的遵从者,就可以实现这些打包的职责
    
    //代理在iOS开发中,一般可以用于响应特定的操作,或从外部数据源取回数据,但无需了解是何种数据源
    
    struct Role {
        var name : String
    }
    
    protocol Player {
        var role : Role {get}
        mutating func Play()
    }
    
    protocol GameDelegate {
        func start(with player : Player) -> Int
        func rolePK(with player : Player, armed :Bool) -> Int
        func end(with player : Player ) -> Int
    }
    
    struct GameAgent : GameDelegate {
        func start(with player: Player) -> Int {
            print(player.role.name, "开始进入游戏,获得经验2000")
            return 2000
        }
        
        func rolePK(with player: Player, armed: Bool) -> Int {
            if armed {
                print(player.role.name,"开始PK,您有武器,获得经验5000")
                return 5000
            }else {
                print(player.role.name,"开始pk","您没有武器,获得经验2500")
                return 2500
            }
        }
        
        func end(with player: Player) -> Int {
            print(player.role.name,"正常退出,获得经验1000")
            return 1000
        }
        
    }
    
    struct MirPlayer : Player {
        var exp : Int
        var gameAgent : GameAgent?
        
        var role: Role
        mutating func Play() {
            if let gameAgent = gameAgent {
                print("您使用了代玩")
                exp += gameAgent.start(with: self)
                exp += gameAgent.rolePK(with: self, armed: true)
                exp += gameAgent.end(with: self)
            }else {
                print("您没有使用,不能自动升级")
            }
        }
        
    }
    
    let role = Role(name: "小波")
    var playerN = MirPlayer(exp: 0, gameAgent: nil, role: role)
    playerN.Play()
    
    let role2 = Role(name: "土豪玩家")
    let agent = GameAgent()
    var palyerE = MirPlayer(exp: 0, gameAgent: agent, role: role2)
    palyerE.Play()
    
    //协议的扩展和协议的约束
    
    //协议扩展:给无源码的添加协议(给系统类添加协议)
    
    let a = 1
    
    protocol ShowHint {
        func hint() -> String
    }
    
    extension Int : ShowHint {
        func hint() -> String {
            return "整数:\(self)"
        }
    }
    
    a.hint()
    (-1).hint()
    
    
    //如果一个类型预遵从了协议,可以直接扩展协议
    
    struct Lesson {
        var name : String
        var description : String {
            return "课程名是:" + name
        }
    }
    
    1.description
    
    //extension Lesson : CustomStringConvertible{
    //    var description: String {
    //        retu
    //    }
    //}
    
    //扩展约束:可以在扩展协议的同时,加上限定条件.where语句
    extension ShowHint where Self: CustomStringConvertible {
        func hint2() -> String {
            return "我是一个能显示成字符串的类型" + self.description
        }
    }
    1.hint2()
    
    
    //集合类型Collection也是一种协议Iterator.Element指代其中的元素
    
    let array = [1,2,3,4,5]
    extension Collection where Iterator.Element :CustomStringConvertible {
        func newDesc() -> String {
            let itemAsText = self.map{ $0.description }
            return "该集合类型元素数目是\(self.count),元素的值依次是" + itemAsText.joined(separator: ",")
        }
    }
    
    array.newDesc()
    print(array)
    
    
    //协议集合类型,因为协议可以作为类型使用,可以把遵从相同协议的实例放到一个协议类型的数组
    
    let arry:[CustomStringConvertible] = [1,2,3,"hha"]
    for element in arry {
        print(element)
    }
    
    
    //协议继承和默认实现
    
    //class不能多重继承,结构体进行协议扩展,相当于多重继承
    
    protocol MyPrintable : CustomStringConvertible, CustomPlaygroundDisplayConvertible {
    
    }
    //
    struct MyContent {
        var text : String
        var mycustomtext : String
    
    }
    
    extension MyPrintable {
       var playgroundDescription: Any {
            return "PlayfroundQuickLook is departure"
        }
    }
    
    
    //提供默认实现,不需要每个继承他的结构体和枚举都具体实现
    
    
    extension MyContent : MyPrintable {
        
        var playgroundDescription: Any {
            return self.mycustomtext
        }
        
       
        var description: String {
            return self.text
        }
    }
    
    
    let mycontent1 = MyContent(text: "内容", mycustomtext: "保留文字")
    mycontent1.description
    
    //swift中协议继承,提倡多协议组合的做法
    
    
    //类专用协议 多加个关键字class 用的少
    protocol OnlyForClass : class, CustomStringConvertible, CustomPlaygroundDisplayConvertible {
        
    }
    
    class MyText : OnlyForClass {
        
        var description: String {
            return "aaa"
        }
        
        var playgroundDescription: Any {
            return "bbbb"
        }
        
        
    }
    //报错,只能由class来继承
    //struct : MyStruct : OnlyForClass
    //{
    //
    //}
    
    //协议组合 协议1 & 协议2 & 协议3
    
    protocol Ageable {
        var age : Int {get}
    }
    
    protocol Nameable {
        var name : String { get }
    }
    
    struct StudentT : Ageable,Nameable {
        var age : Int
        var name : String
    }
    
    struct TeacherT : Ageable,Nameable {
        var age : Int
        var name : String
        var title : String
        
    }
    
    func wish(someone : Ageable & Nameable) {
        print("祝",someone.name,someone.age,"岁生日快乐!")
    }
    
    let studentt1 = StudentT(age: 10, name: "Tom")
    let teachert1 = TeacherT(age: 30, name: "Bob", title: "Professor")
    
    wish(someone: studentt1)
    wish(someone: teachert1)
    
    //没有很严格的意义,灵活性强,拆小功能,大的功能用小的功能组合
    
    
    //协议的检查和转换 使用is和as类型操作符来检查协议遵从与否,或转换成特定的协议
    
    protocol Slogan {
        var desc: String { get }
    }
    
    protocol Coder : Slogan {
        var name:String { get }
        
    }
    
    struct JavaCode : Coder {
        
        var name: String
        var desc: String {
            return "我会Java我流弊"
        }
        
        
    }
    
    struct JScoder : Coder {
        var name: String
        var desc: String {
            return "我会JS我很潮"
        }
    }
    
    struct NewBie {
        var name : String
    }
    
    let java1 = JavaCode(name: "小牧")
    let js1 = JScoder(name: "小可")
    let newbie1 = NewBie(name: "小波")
    let coders = [java1,js1,newbie1] as [Any]
    for coder in coders {
        if let coder = coder as? Coder {
            print(coder.name,coder.desc)
        }else {
            print("你不是一个程序员")
        }
        
        if let newbie = coder as? NewBie {
            print("你是菜鸟~",newbie.name)
        }
    }
    
    

    Demo拉取地址:
    https://gitee.com/xgkp/swiftBasicProtocol.git

    明天开始放假,最后一个工作日了,回顾一年写的代码,还是有优化空间的,留作来年小尾巴~~~~

    相关文章

      网友评论

          本文标题:Swift面向协议基础

          本文链接:https://www.haomeiwen.com/subject/uwxezctx.html