Swift學習筆記第六篇(類,屬性,方法)

來源:互聯網
上載者:User
類定義

我們通過關鍵字class和struct來分別表示類和結構體,並在一對大括弧中定義它們的具體內容

/* class SomeClass { // class definition goes here } struct SomeStructure { // structure definition goes here } */

類和結構體共同點
/*
1.定義屬性用於儲存值
2.定義方法用於提供功能
3.定義附屬指令碼用於訪問值
4.定義構造器用於產生初始化值
5.通過擴充以增加預設實現的功能
6.符合協議以對某類提供標準功能
*/

/*
類和結構體共同點
1.繼承允許一個類繼承另一個類的特徵
2.類型轉換允許在運行時檢查和解釋一個類執行個體的類型
3.解構器允許一個類執行個體釋放任何其所被分配的資源
4.引用計數允許對一個類的多次引用
*/

struct Area {    var width = 0    var height = 0}class JackModel{    var area = Area()    var isFemale = false    var name : String?}let someArea = Area()let someJackModel = JackModel()print("The width of Area is \(someArea.width)")someJackModel.area.width = 1040print("The width of Area is \(someJackModel.area.width)")

注意: 與 Objective-C 語言不同的是,Swift 允許直接設定結構體屬性的子屬性。上面的最後一個例子,就是直接設定了someVideoMode中resolution屬性的width這個子屬性,以上操作並不需要重新設定resolution屬性

// 結構體類型的成員逐一構造器 類就沒有這種逐一構造方法let hehe = Area(width:100,height:200)print(hehe.height)

/*
1.結構體和枚舉—>實值型別被賦予給一個變數,常數或者本身被傳遞給一個函數的時候,實際上操作的是其的拷貝。
2.類——————>與實值型別不同,參考型別在被賦予到一個變數、常量或者被傳遞到一個函數時,操作的是引用,其並不是拷貝。因此,引用的是已存在的執行個體本身而不是其拷貝
*/ 恒等運算子

判斷兩個類是否完全相等
// 恒等運算子
/*
因為類是參考型別,有可能有多個常量和變數在後台同時引用某一個類執行個體。(
對於結構體和枚舉來說,這並不成立。因為它們作為實值型別,在被賦予到常量、變數或者傳遞到函數時,其值總是會被拷貝。
1.請注意“等價於”(用三個等號表示,===) 與“等於”(用兩個等號表示,==)的不同
2.“等價於”表示兩個類類型(class type)的常量或者變數引用同一個類執行個體。
3.“等於”表示兩個執行個體的值“相等”或“相同”
*/ 類和結構體的選擇

/*
然而,結構體執行個體總是通過值傳遞,類執行個體總是通過引用傳遞。
這意味兩者適用不同的任務。當你在考慮一個工程項目的資料構造和功能的時候,你需要決定每個資料構造是定義成類還是結構體。
1.結構體的主要目的是用來封裝少量相關簡單資料值。
2.有理由預計一個結構體執行個體在賦值或傳遞時,封裝的資料將會被拷貝而不是被引用。
3.任何在結構體中儲存的實值型別屬性,也將會被拷貝,而不是被引用。
4.結構體不需要去繼承另一個已存在類型的屬性或者行為。
5.實際中,這意味著絕大部分的自訂資料構造都應該是類,而非結構體。
*/ 值傳遞和值copy

/*
Swift 中字串(String),數組(Array)和字典(Dictionary)類型均以結構體的形式實現。
這意味著String,Array,Dictionary類型資料被賦值給新的常量(或變數),或者被傳入函數(或方法)中時,它們的值會發生拷貝行為(值傳遞方式
Objective-C中字串(NSString),數組(NSArray)和字典(NSDictionary)類型均以類的形式實現,這與Swfit中以值傳遞方式是不同的。NSString,NSArray,NSDictionary在發生賦值或者傳入函數(或方法)時,不會發生值拷貝,而是傳遞已存在執行個體的引用。
*/ 屬性

/*
簡單來說,一個儲存屬性就是儲存在特定類或結構體的執行個體裡的一個常量或變數,
儲存屬性可以是變數儲存屬性(用關鍵字var定義),也可以是常量儲存屬性(用關鍵字let定義)
*/

// 主要介紹下延遲儲存屬性 lazy關鍵字
/*
1.可以理解為懶載入,這裡有關鍵字給屬性輔助
2.必須將延遲儲存屬性聲明成變數(使用var關鍵字),因為屬性的值在執行個體構造完成之前可能無法得到。而常量屬性在構造過程完成之前必須要有初始值,因此無法聲明成延遲屬性。
*/

class DataImporter {    /*     DataImporter 是一個將外部檔案中的資料匯入的類。     這個類的初始化會消耗不少時間。     因此一開始沒用到就初始化會沒必要 用懶載入進行操作     */    var fileName = "data.txt"}class DataManager {    lazy var importer = DataImporter()    var data = String()    // 這是提供資料管理功能}let manager = DataManager()manager.data.append("mikejing")manager.data.append("!!!")print(manager.data)// DataImporter 執行個體的 importer 屬性還沒有被建立print(manager.importer.fileName)// DataImporter 執行個體的 importer 屬性現在被建立了// 輸出 "data.txt”
getter setter didSet willSet方法
// getter setter willSet didSetclass StepCounter {    var totalSteps: Int = 0 {//        get {//            return totalSteps//        }//        set {//            totalSteps = newValue//        }        // 在設定setter方法之前調用        willSet(newTotalSteps) {            print("will set \(newTotalSteps)")        }        // 賦值的時候調用        didSet {            print("did set")            if totalSteps > oldValue  {                print("add \(totalSteps - oldValue) steps")            }        }    }}let name = StepCounter()name.totalSteps = 100// will set 100// did set// add 100 stepsname.totalSteps = 540/* will set 540 did set add 440 steps */name.totalSteps = 775/* will set 775 did set add 235 steps */


func方法

結構體和枚舉能夠定義方法是 Swift 與 C/Objective-C 的主要區別之一。在 Objective-C 中,類是唯一能定義方法的類型。但在 Swift 中,你不僅能選擇是否要定義一個類/結構體/枚舉,還能靈活的在你建立的類型(類/結構體/枚舉)上定義方法。

class Counter {    var count = 0    func increment() {        count += 1    }    // by是外部參數  amount 是內部參數    func increment(by amount: Int) {        count += amount    }    func reset() {        count = 0    }}let counter = Counter()// the initial counter value is 0counter.increment()// the counter's value is now 1counter.increment(by: 5)// the counter's value is now 6counter.reset()// the counter's value is now 0
執行個體方法中修改實值型別的屬性 mutating

/* 1.在樣本方法中修改實值型別 Modifying Value Types from Within Instance Methods
* 2.結構體和枚舉是實值型別。一般情況下,實值型別的屬性不能在它的執行個體方法中被修改。
* 3.mutating方法就可以從方法內部改變它的屬性
*/

// 方法一 修改原來建立的類型變數struct Point{    var x = 0.0    var y = 0.0    mutating func movePoint(x deltaX:Double,y deltaY:Double) {        x += deltaX        y += deltaY    }}var pointA = Point(x:1.0,y:1.0)print("x=\(pointA.x),y=\(pointA.y)")pointA.movePoint(x: 9, y: 9)print("x=\(pointA.x),y=\(pointA.y)")

注意:不能在結構體類型常量上調用變異方法,因為常量的屬性不能被改變,即使想改變的是常量的變數屬性也不行

// 方法二 :另一種替換的方法  self 新建立出來的對象會替換之前的值struct PointB{    var x1 = 0.0    var y1 = 0.0    mutating func movePointB(x deltaX:Double,y deltaY:Double){        self = PointB(x1:x1 + deltaX,y1:y1+deltaY)    }}var pointB = PointB(x1:200,y1:200)print("x=\(pointB.x1),y=\(pointB.y1)")pointB.movePointB(x: 9, y: 9)print("x=\(pointB.x1),y=\(pointB.y1)")



筆記地址

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.