一、類的定義
Swift與Objective-C定義類的差別
Objective-C:一般需要2個檔案,1個.h聲明檔案和1個.m實作檔案
Swift:隻需要1個.swift檔案
Swift中類的定義格式
class 類名 {
// ... 屬性和方法
}
二、屬性
1.什麼是屬性
Swift中的屬性(Properties),就類似于其他面向對象語言中的成員變量
2.屬性的分類
按照官方文檔的說明,屬性可以分為以下幾種
(1)存儲屬性(Stored Properties)
(2)計算屬性(Computed Properties)
(3)類型屬性(Type Properties)
3.存儲屬性
1)簡單說明
存儲屬性:存儲屬性就是存儲在對象(執行個體)中的一個變量或者常量
存儲屬性類似于其他面向對象語言中的成員變量
class Person {
var age: Int =
var height: Double =
let life =
}
說明:
Person類中定義了3個存儲屬性
2個變量存儲屬性:Int類型的age、Double類型的height
1個常量存儲屬性:Int類型的life
系統并不會自動初始化上面的3個存儲屬性,需要進行手動初始化
2)存儲屬性的讀寫
如何讀寫存儲屬性?
直接通過點運算符(.),就可以讀寫某個對象的存儲屬性
class Person {
var age: Int =
let life =
}
let p = Person()
p.age =
print("p的生命是\(p.life), p的年齡是\(p.age)")
說明:
第5行:建立Person對象
第6行:給對象p的age屬性指派
第7行:通路對象p的life屬性值和age屬性值
3)延遲存儲屬性
什麼是延遲存儲屬性?
延遲存儲屬性是第一次使用時才進行初始化的屬性
使用@lazy來辨別一個延遲存儲屬性
class Person {
@lazy var dog: String = String()
}
let p = Person()
println(p.dog)
說明:
執行第5行代碼時,才會去初始化dog屬性,才真正建立了String對象
延遲存儲屬性的使用注意:延遲存儲屬性必須是變量,不能是常量
延遲存儲屬性的好處:讓某些資源用到時再去加載,避免一些不必要的資源浪費
4.計算屬性
(1)什麼是計算屬性
跟存儲屬性不一樣的是,計算屬性不是直接存儲值,而是提供get和set
get:用來取值,封裝取值的過程
set:用來設值,封裝設值的過程
(2)代碼示例:
class Square {
// 正方形的寬度
var width: Double =
// 正方形的周長
var girth: Double {
get {
// 周長 = 寬度 * 4
return width *
}
set(newGirth) {
// 寬度 = 周長 / 4
width = newGirth /
}
}
}
計算屬性舉例:
let s = Square()
s.width =
print(s.girth)
s.girth =
print(s.width)
說明:
第3行代碼:調用girth屬性的get,輸出結果是40
第4行代碼:調用girth屬性的set,并且把200傳遞給newGirth參數
第5行代碼:輸出結果是50
(3)簡便的set
set也可以不特意指定新值的參數名,新值的預設參數名叫做newValue
var girth: Double {
get {
return width *
}
set {
width = newValue /
}
}
s.girth =
說明:
執行第9行代碼時:第6行中newValue的值就是200
(4)計算屬性的使用注意
1)因為計算屬性的值不是固定的,是以隻能用var修飾計算屬性,不能用let
class Square {
var girth: Double {
get {
return girth
}
set(newGirth) {
girth = newGirth
}
}
}
說明:上面的代碼會引發死循環,第4行代碼會引發循環調用get,第7行代碼會引發循環調用set。
2)一個屬性不能既是存儲屬性,又是計算屬性
class Square {
var girth: Double = {
get {
return
}
set() {
}
}
}
說明:上面的代碼是錯誤的
(5)隻讀計算屬性
什麼是隻讀計算屬性?隻提供get,沒有set的計算屬性
class Square {
var width: Double =
var girth: Double {
get {
return width *
}
}
}
let s = Square()
s.girth =
說明:第10行代碼會報錯
隻讀計算屬性的簡寫。隻讀計算屬性可以省略get關鍵字
class Square {
var width: Double =
var girth: Double {
return width *
}
}
let s = Square()
s.girth =
說明:第8行代碼會報錯
5.類型屬性
(1)什麼是類型屬性?
用class關鍵字修飾的屬性,就是類型屬性,也可以稱為“類屬性”
class修飾的類型屬性隻能是計算屬性,不能是存儲屬性
代碼示例:
class Circle {
class var PI : Double {
return
}
}
說明:第2行定義的屬性PI,就是一個類型屬性
(2)類型屬性的特點
一個類隻會有一份,類的多個執行個體對象都共享這唯一的一份
類型屬性的使用:類型屬性不依賴于對象而存在,是以用類名來通路
println(Circle.PI)
三、屬性螢幕
1.什麼是屬性螢幕?
有時,需要在屬性值被修改的時候做出響應,這種情況下就可以用屬性螢幕
屬性螢幕,可以監視屬性值的修改過程
計算屬性可以直接在set中監聽屬性值的改變,而存儲屬性沒有set
可以為存儲屬性添加willSet和didSet兩個屬性螢幕
(1)willSet:
在設定新的屬性值之前調用
會将新的屬性值作為參數傳入,參數名預設是newValue
(2)didSet:
在設定新的屬性值之後調用
會将舊的屬性值作為參數傳入,參數明預設是oldValue
2.代碼示例
class Square {
var width: Double = {
willSet {
print("willSet---\(newValue)")
}
didSet {
print("didSet---\(oldValue)")
}
}
}
let s = Square()
s.width =
列印結果:
willSet—10.0
didSet—0.0
3.使用注意
class Square {
var width: Double = {
willSet { }
didSet { width = }
}
}
let s = Square()
s.width =
print(s.width)
代碼說明:
willSet和didSet在屬性初始化過程中不會被調用,隻會當屬性的值在初始化之外的地方被設定時被調用
第2行代碼的初始化不會引發willSet和didSet的調用
第8行代碼的指派會引發willSet和didSet的調用
如果在didSet螢幕裡為屬性指派,這個值會替換之前設定的值
第4行對width屬性進行了再次指派,覆寫了第8行賦的值,是以第9行的輸出結果是20
willSet、didSet和set、get不能共存