美文网首页
GeekBand-Swift 第二周笔记(结构、枚举、类)

GeekBand-Swift 第二周笔记(结构、枚举、类)

作者: 周一见丶 | 来源:发表于2017-03-01 14:44 被阅读0次

    结构、枚举、类

    • Struct 和 Enum 在栈上,具有值拷贝语义,不要在里面定义引用类型属性。
    • Struct 和 Enum 不支持面向对象,但支持面向协议,适用于轻量级对象。
    • Enum 中可以指定 raw value,类型可以是字符、字符串、整数、浮点数。
      Enum 一般定义一组相关值成员,可以用 switch-case 处理 Enum。
      作为数据模型来说,Struct 比 Class 更加安全、迅速(快很多倍),没有内存泄漏和线程安全的问题。OC 中无法调用 Swift 的 Struct,因为需要继承自 NSObject OC 才可以调用。Struct 亦不能被序列化为 NSData 对象。
      总结下:数据模型较小,不会占用太多栈资源;无需继承,且 Swift 提倡面向协议编程;无需储存为 NSData;无需被 OC 调用;在以上情况满足时,强烈建议使用 Struct 而不是 Class。

    继承、多态、协议

    • 只有类可以继承,子类继承父类属性、方法、下标,实例成员和类型成员都可以继承,子类 is-a 父类,逻辑关系要清楚。
    • 使用 final 阻止子类 override 该成员,类上使用 final 意味着该类不能被继承。
    • 协议本质是一种声明类型,不能创造实例。
      注意:协议变量的内存模型遵从实际变量的内存模型。
      可以使用 is 检查类型是否实现了该协议。协议中只能定义变量属性,不能定义常量属性。
    • mutating and required


      mutating.png
      required.png

    字符串和集合

    String、Array、Set、Dictionary 都是 Struct,其中 String 内存模型稍稍复杂一点,其他三位都是栈中储存一个指针指向真正的对象,那为什么说他们是值类型 Struct 呢?因为他们都是值语义。


    String 内存模型.png
    • String 是一个拥有三个元素的 Struct,有一个指针指向字符串。
      这四位都遵循 copy-on-write 技术,当有人拷贝他们时,只是拷贝了他们的指针,只有当真正的值被更改时,才会复制原来的值到另外一个内存并更改。这样就节省了大量的资源。在程序中,我们尽量不要做无谓的更改,提升效率。
      String 和 Array 都遵循 capacity 的内存分配规则,当容量超过 capacity 时,重新分配内存的代价很大,影响性能,所以最好一开始预估好 capacity,避免增长。


      capacity.png
    • Dictionary 和 Set 都没有 capacity 的概念,但是相对应的 key 和元素都必须有哈希值,支持 Hashable 协议。
      Dictionary 是一个无序的 key-value 集合,key 唯一,value 可重复;
      Set 是一个无序的集合,储存的值不可以重复。

    第二周作业

    第二周作业题目.png

    我的答案

    import UIKit
    import Foundation
    //交通工具类
    class Jiaotong {
        var v: Double
        var w: Double
        init(v: Double, w: Double) {
            self.v = v
            self.w = w
        }
        func move(time: Double, v: Double) {
            let l = time*v
            print("移动距离\(l)")
        }
        deinit {
            print("Over")
        }
    }
    //颜色枚举
    enum Color {
        case white
        case blue
        case yellow
        case black
        case green
        case red
    }
    //火车类继承交通工具
    class Train: Jiaotong {
        var color: Color
        var chexiang = ["One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten"]
        init(color: Color) {
            self.color = color
            super.init(v: 80.0, w: 800.0)
        }
        //便捷初始化器
        convenience init() {
            self.init(color: .white)
        }
        //定义下标
        subscript (i: Int) -> String {
            get {
                return chexiang[i]
            }
            set {
                chexiang[i] = newValue
            }
        }
        //重写父类移动方法
        override func move(time: Double, v: Double) {
            super.move(time: time, v: v)
            print("嗡嗡")
        }
    }
    //飞机的机长结构
    struct Captain {
        let name: String
        var worktime: Double
        init(name: String, worktime: Double) {
            self.name = name
            self.worktime = worktime
            print("The aircraft's captain is \(self.name), he worktime is \(self.worktime) hours.")
        }
        mutating func addWorktime(newWorktime: Double) {
            self.worktime += newWorktime
            print("The aircraft's captain is \(self.name), he worktime is \(self.worktime) hours.")
        }
    }
    //飞机类继承交通工具
    class Aircraft: Jiaotong {
        var color: Color
        var captain: Captain
        //使用可选类型定义初始化器
        init?(color: Color, captain: Captain) {
            //当机长姓名为空时,初始化失败返回 nil
            if captain.name.isEmpty {
                return nil
            }
            self.captain = captain
            self.color = color
            super.init(v: 800.0, w: 50.0)
        }
    //自定义操作符比较这两个类的颜色
        static func == (left: Train, right: Aircraft) -> Bool {
            if left.color == right.color {
                return true
            }
                return false
        }
        override func move(time: Double, v: Double) {
            super.move(time: time, v: v)
            print("呼呼")
        }
    }
    //新建各个类的实例,实现里面的方法
    var jiaotong = Jiaotong(v: 0.0, w: 0.0)
    var train1 = Train()
    var train2 = Train(color: .green)
    var captain1 = Captain(name: "Davie", worktime: 1055.5)
    var aircraft1 = Aircraft(color: .white, captain: captain1)
    
    jiaotong.move(time: 10, v: 10.5)
    train1.move(time: 50.5, v: 135.6)
    aircraft1?.move(time: 34.5, v: 800.0)
    aircraft1?.captain.addWorktime(newWorktime: 10.5)
    
    //用下标遍历车厢元素
    for i in 0...9 {
        print(train1[i])
    }
    //先判断飞机实例是否为空,再比较火车和飞机的实例颜色是否相同
    if let aircraftLet = aircraft1{
        if train1 == aircraftLet {
            print("The train1's color is the same as the aircraft.")
        }
        else {
            print("The train1's color is not the same as the aircraft.")
        }
    }
    else {
        print("The aircraft has not been initialized yet.")
    }
    //可选类型赋值为 nil 可以验证析构器
    aircraft1 = nil
    

    相关文章

      网友评论

          本文标题:GeekBand-Swift 第二周笔记(结构、枚举、类)

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