GeekBand-Swift 第二周筆記(結構、枚舉、類)

結構、枚舉、類

  • 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
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容