類的屬性介紹
Swift中屬性有多種
存儲(chǔ)屬性:存儲(chǔ)實(shí)例的常量和變量
計(jì)算屬性:通過(guò)某種方式計(jì)算出來(lái)的屬性
類屬性:與整個(gè)類自身相關(guān)的屬性
存儲(chǔ)屬性
存儲(chǔ)屬性是最簡(jiǎn)單的屬性哪自,它作為類實(shí)例的一部分晶框,用于存儲(chǔ)常量和變量
可以給存儲(chǔ)屬性提供一個(gè)默認(rèn)值品山,也可以在初始化方法中對(duì)其進(jìn)行初始化
下面是存儲(chǔ)屬性的寫法
age和name都是存儲(chǔ)屬性,用來(lái)記錄該學(xué)生的年齡和姓名
chineseScore和mathScore也是存儲(chǔ)屬性,用來(lái)記錄該學(xué)生的語(yǔ)文分?jǐn)?shù)和數(shù)學(xué)分?jǐn)?shù)
class Student {
// 存儲(chǔ)屬性
var age : Int = 0
var name : String?
var chineseScore : Double = 0.0
var mathScore : Double = 0.0
}
// 創(chuàng)建學(xué)生對(duì)象
let stu = Student()
// 給存儲(chǔ)屬性賦值
stu.age = 10
stu.name = "why"
stu.chineseScore = 89.0
stu.mathScore = 98.0
計(jì)算屬性
計(jì)算屬性并不存儲(chǔ)實(shí)際的值,而是提供一個(gè)getter
和一個(gè)可選的setter
來(lái)間接獲取和設(shè)置其它屬性
計(jì)算屬性一般只提供getter
方法
如果只提供getter
,而不提供setter
,則該計(jì)算屬性為只讀屬性弊攘,并且可以省略get{}
下面是計(jì)算屬性的寫法
averageScore是計(jì)算屬性,通過(guò)chineseScore和mathScore計(jì)算而來(lái)的屬性
在setter方法中有一個(gè)newValue變量,是系統(tǒng)指定分配的
class Student {
// 存儲(chǔ)屬性
var age : Int = 0
var name : String?
var chineseScore : Double = 0.0
var mathScore : Double = 0.0
// 計(jì)算屬性
var averageScore : Double {
get {
return (chineseScore + mathScore) / 2
}
// 死循環(huán)抢腐,在內(nèi)部又會(huì)調(diào)用set方法
// newValue是系統(tǒng)分配的變量名,內(nèi)部存儲(chǔ)著新值
set {
self.averageScore = newValue
}
}
}
// 獲取計(jì)算屬性的值
print(stu.averageScore)
類屬性
類屬性是與類相關(guān)聯(lián)的姑曙,而不是與類的實(shí)例相關(guān)聯(lián)
所有的類和實(shí)例都共有一份類屬性.因此在某一處修改之后,該類屬性就會(huì)被修改
類屬性的設(shè)置和修改,需要通過(guò)類來(lái)完成
下面是類屬性的寫法
類屬性可以使用static
來(lái)修飾
courseCount是類屬性,用來(lái)記錄學(xué)生有多少門課程
class Student {
// 存儲(chǔ)屬性
var age : Int = 0
var name : String?
var chineseScore : Double = 0.0
var mathScore : Double = 0.0
// 計(jì)算屬性
var averageScore : Double {
return (chineseScore + mathScore) / 2
}
// 類屬性
static var englishScore:Double = 95.5
}
// 設(shè)置類屬性的值
Student.englishScore = 90.5
// 取出類屬性的值
print(Student.englishScore)
懶加載屬性
蘋果的設(shè)計(jì)思想:希望所有的對(duì)象在使用時(shí)才真正加載到內(nèi)存中
在OC中我們可以重寫get方法來(lái)進(jìn)行懶加載
Swift用lazy
關(guān)鍵字可以用于定義某一個(gè)屬性懶加載
lazy的作用是只會(huì)賦值一次
懶加載的本質(zhì)是,在第一次使用的時(shí)候執(zhí)行閉包,將閉包的返回值賦值給屬性
懶加載的使用
lazy var 變量: 類型 = { 創(chuàng)建變量代碼 }()
lazy var teacher:[String] = {
()->[String] in
return ["Mr Zhang", "Mr Li", "Mr Yang"]
}()
student.teacher
幾種屬性的區(qū)別
存儲(chǔ)屬性 —— 實(shí)實(shí)在在存儲(chǔ)常量和變量的
計(jì)算屬性 —— 依賴于存儲(chǔ)屬性,通過(guò)計(jì)算得出來(lái)迈倍,它提供getter和setter方法間接訪問(wèn)和設(shè)置值
類屬性 —— 本質(zhì)是一個(gè)全局屬性伤靠,在類里限定了其作用域,用關(guān)鍵字static修飾
懶加載屬性 —— 用關(guān)鍵字lazy修飾啼染,必須進(jìn)行初始化宴合,非實(shí)例屬性懶加載時(shí)在大括號(hào){}后面要加上()
全局屬性 —— 類外面的屬性,作用域全局
總結(jié):
存儲(chǔ)屬性迹鹅,最先被初始化
構(gòu)造方法卦洽,僅次于存儲(chǔ)屬性調(diào)用,可以在這里對(duì)存儲(chǔ)屬性進(jìn)行賦值
懶加載屬性斜棚、類屬性阀蒂、全局屬性都是在第一次使用的時(shí)候初始化一次,以后調(diào)用都不再初始化
當(dāng)懶加載屬性是基于一個(gè)存儲(chǔ)屬性計(jì)算的時(shí)候弟蚀,切勿使用懶加載屬性蚤霞,采用計(jì)算屬性
監(jiān)聽屬性的改變
在OC中我們可以重寫set方法來(lái)監(jiān)聽屬性的改變
Swift中可以通過(guò)屬性觀察者來(lái)監(jiān)聽和響應(yīng)屬性值的變化
通常是監(jiān)聽存儲(chǔ)屬性和類屬性的改變.(對(duì)于計(jì)算屬性,不需要定義屬性觀察者义钉,因?yàn)榭梢栽谟?jì)算屬性的setter中直接觀察并響應(yīng)這種值的變化)
定義觀察者
willSet:在屬性值被存儲(chǔ)之前設(shè)置昧绣。此時(shí)新屬性值作為一個(gè)常量參數(shù)被傳入。該參數(shù)名默認(rèn)為newValue捶闸,可以自定義
didSet:在新屬性值被存儲(chǔ)后立即調(diào)用夜畴。與willSet相同,此時(shí)傳入的是屬性的舊值删壮,默認(rèn)參數(shù)名為oldValue贪绘,可以自定義
willSet與didSet只有在屬性改變時(shí)才會(huì)調(diào)用,在初始化時(shí)不會(huì)去調(diào)用這些監(jiān)聽方法
class Student {
var name:String?{
// 屬性即將改變,還未改變時(shí)會(huì)調(diào)用的方法
// 可以給newValue自定義名稱
willSet(new){
print("willSet---")
// 在該方法中有一個(gè)默認(rèn)的系統(tǒng)屬性newValue,用于存儲(chǔ)新值
if let new = new {
print(new)
}
}
// 屬性值已經(jīng)改變了,會(huì)調(diào)用的方法
didSet{
print("didSet---")
// 在該方法中有一個(gè)默認(rèn)的系統(tǒng)屬性oldValue,用于存儲(chǔ)舊值
if let oldValue = oldValue {
print(oldValue)
}
}
}
}
var student = Student()
// 在賦值時(shí),監(jiān)聽該屬性的改變
student.name = "Zhangsan"
student.name = "Lisi"
屬性繼承與重寫
屬性繼承:子類可以繼承父類的屬性醉锅,包括存儲(chǔ)屬性兔簇、計(jì)算屬性和類型屬性,還可以繼承父類的屬性觀察器。
屬性重寫
無(wú)論繼承的是存儲(chǔ)屬性還是計(jì)算屬性垄琐,子類都可以通過(guò)提供getter和setter對(duì)屬性進(jìn)行重寫
可以將一個(gè)繼承的屬性重寫為一個(gè)讀寫屬性
不可以將繼承來(lái)的讀寫屬性重寫為只讀屬性
如果重寫時(shí)提供了setter方法边酒,一定要提供getter方法
屬性觀察器重寫
無(wú)論父類有沒(méi)有為該屬性添加屬性觀察器,子類都可以添加屬性觀察器
如果父類已經(jīng)添加了屬性觀察器狸窘,當(dāng)屬性發(fā)生變化時(shí)墩朦,父類與子類都會(huì)得到通知
屬性觀察器不能用于計(jì)算屬性,只能用于存儲(chǔ)屬性翻擒,因?yàn)橛?jì)算屬性在setter里就可以獲取到屬性的變化
實(shí)例方法
實(shí)例方法屬于特定類實(shí)例氓涣、結(jié)構(gòu)體實(shí)例或者枚舉實(shí)例的函數(shù)
這里的方法其實(shí)就是函數(shù),只不過(guò)放在類陋气、結(jié)構(gòu)體和枚舉中時(shí)稱之為方法
self 屬性
每一個(gè)類的實(shí)例都隱含一個(gè)叫做 self的屬性劳吠,可以使用 self訪問(wèn)當(dāng)前類中的屬性和方法
class Student {
var str = "Hello, playground"
func say(info:String) {
print(info)
}
func eat(food:String){
//self指向的是當(dāng)前類的實(shí)例
self.say(info: food)
print("吃\(food)")
}
}
var stu = Student()
stu.eat(food: "米飯")
值類型在實(shí)例方法中修改屬性和調(diào)用方法
值類型默認(rèn)情況下,不能在實(shí)例方法中修改屬性
不能用self調(diào)用其他的函數(shù)
可以在函數(shù)前放一個(gè)mutating
關(guān)鍵字來(lái)實(shí)現(xiàn)
struct Student {
var str = "Hello, playground"
mutating func say(info:String) {
print(info)
self.str = "Hello World"
print(self.str)
}
mutating func eat(food:String){
self.say(info: food)
print("吃\(food)")
}
}
類型方法
在函數(shù)前使用 static關(guān)鍵字(能在類巩趁、結(jié)構(gòu)體中使用)
在函數(shù)前使用 class關(guān)鍵字(只能在類中使用)
static func play(){
print("play")
}
class func study(){
print("study")
}
class 和 static 總結(jié)
class 和 static 相同點(diǎn)
可以修飾方法,static 修飾的方法叫做靜態(tài)方法,class修飾的叫做類方法
都可以修飾計(jì)算屬性
class 和 static 不同點(diǎn)
class 不能修飾存儲(chǔ)屬性痒玩,static 可以修飾存儲(chǔ)屬性,static修飾的存儲(chǔ)屬性稱為靜態(tài)變量(常量)
class 修飾的計(jì)算屬性可以被重寫,static 修飾的不能被重寫
static 修飾的靜態(tài)方法不能被重寫,class 修飾的類方法可以被重寫
class 修飾的類方法被重寫時(shí),可以使用static 讓方法變?yōu)殪o態(tài)方法
class 修飾的計(jì)算屬性被重寫時(shí),可以使用static 讓其變?yōu)殪o態(tài)屬性,但它的子類就不能被重寫了
class 只能在類中使用,但是static 可以在類,結(jié)構(gòu)體,或者枚舉中使用
最后編輯于 :2020.09.11 09:20:40
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者