屬性將值 ( values ) 與特定類 ( class )、結構 ( struct ) 或枚舉 ( enumeration) 相關聯。存儲屬性將常數和變數值存儲為實例的一部分,而計算屬性則計算(而不是存儲)值。計算屬性由類,結構和枚舉提供。存儲的屬性僅由類和結構提供。
存儲和計算屬性通常與特定類型的實例相關聯。但是,屬性也可以與類型本身相關聯。這些屬性稱為類型屬性。
此外,我們可以定義屬性觀察器以監視屬性值的更改,我們使用自定義操作對其進行響應。可以將屬性觀察器添加到自己定義的存儲屬性中,也可以添加到子類從其父類繼承的屬性中。
有點搞混了吧?讓我整理一下:
儲存屬性( stored propert ):在實體內儲存常數或變數,可以用於類別及結構。
計算屬性( computed property ):在實體內計算一個值,可以用於類別、結構及列舉。
型別屬性( type property ):與前兩個不同,這是屬於型別本身的屬性。
屬性觀察器( property observer ):用來觀察屬性值的變化,並以此觸發一個自定義的操作。
儲存屬性 ( stored property ) 為一個儲存在特定型別 ( 類別或結構 ) 的常數或是變數。可以在定義儲存屬性時指定預設值,也可以在建構過程中設置或修改儲存屬性的值:
在上面我們創造了 GameSet 的 Struct,在裡面我們設置了變數 hpMAX 及常數 mpMAX,而在我們初始化時賦予 hpMAX 及 mpMAX 值,而常數mpMAX 在初始化之後就無法做更改了。
如果我們實例化一個結構給一個常數,那我們將無法去更改其數值:
因為結構 ( struct ) 是值型別 ( value type ),所以當實體宣告為常數時,裡面的屬性是無法做修改的!
而類別 ( class ) 是參考型別,所以就算宣告為常數,也是可以去修改其內部的屬性,因為他並不會儲存進記憶體中,只是將這個常數儲存為參考,而不是存為實體。
延遲儲存性質是當第一次被呼叫時才會計算其初始值的屬性,在屬性宣告前面加一個 lazy 來表示這是一個延遲屬性。
・延遲儲存屬性只能用在,因為屬性的值在建構完全之前可能無法得到,而常數在建構完全之前就必須要有初始值。
除了儲存屬性外,類別、結構和列舉還可以定義計算屬性 ( computed property ),計算屬性不直接儲存值,而是提供一個 getter ( 使用關鍵字 “get ) 來存取值,以及一個可選的 setter ( 關鍵字 set ) 來間接設置其他屬性的值。
可以將 setter 簡化,省略傳入的參數時,Swift 會提供一個內建的參數名稱 newValue。以下將前面定義的類別 GameSet中的 setter 簡化:
計算屬性的 setter 是可選的,所以依照需求可以只寫 getter,這時可以將計算屬性簡化,以下修改自前面定義的類別 GameSet:
上述程式中,因為計算屬性只有 getter,所以 getter 可以省略掉關鍵字 get 及大括號 { }
屬性觀察器 ( property observer ) 會監控和回應屬性值的變化,每次屬性被設置新的值都會呼叫屬性觀察器。以下為兩個可以使用的屬性觀察器:
・willSet:在設置新的值之前呼叫,會將這個新的值當做一個常數參數傳入,如果不命名這個參數名稱時,會有一個內建的參數名稱 newValue。
・didSet:在新的值被設置之後立即呼叫,會將舊的屬性值當做參數傳入,這個參數可以自己命名,或直接使用內建的參數名稱 oldValue。
型別屬性 ( type property ) 是屬於這個型別 ( 類別、結構或列舉 ) 的屬性,無論生成了多少這個型別的實體,型別屬性都只有唯一一份。
型別屬性使用於定義所有從這個型別生成的實體共享的資料。
・儲存型的型別屬性一定要有預設值,因為型別本身沒有建構器,無法在初始化過程中設值給型別屬性。
・儲存型的型別屬性是延遲初始化的,只有在第一次被呼叫時才會被初始化,所以不需要對其使用 lazy。
型別屬性是使用 static 關鍵字作宣告變數或常數。
在為類別宣告計算型的型別屬性時,依照需求可以改用關鍵字 class 來支持子類別對父類別的實作覆寫 ( override ),也就是在將一個類別A的計算型的型別屬性以 class 宣告後,之後新的類別B繼承這個類別A時,可以覆寫這個型別屬性。
設置儲存型跟計算型的型別屬性如下:
上述程式中,計算型的型別屬性只有 getter,實際上可以定義有 getter 跟 setter 的計算型的型別屬性,使用方法與先前介紹的計算型屬性相同。
與實體的屬性一樣,型別屬性的存取也是使用點語法 ( dot syntax ),但是型別屬性是向型別本身存取和設置,而不是向實體
今天的 Properties 就到這裡囉!如果有其他的問題歡迎留言或是寄信給我!(*´∀`)