類屬性
/*
存儲屬性
其實Swift中的存儲屬性就是以前學習OC中的普通屬性, 在結構體或者類中定義的屬性, 默認就是存儲屬性
*/
struct Person {
var name: String
var age: Int
}
var p = Person(name: "xiaohange", age: 26)
print("name = \(p.name) age = \(p.age)")
p.name = "HaRi"
p.age = 28
print("name = \(p.name) age = \(p.age)")
/*
常量存儲屬性
常量存儲屬性只能在定義時或構造時修改, 構造好一個對象之後不能對常量存儲屬性進行修改
*/
struct Person2 {
var name: String
var age : Int
let card: String // 常量 ID Card
}
var p2 = Person2(name: "HaRi", age: 24, card: "1234")
p2.name = "helloName"
p2.age = 25
// 構造好對象以後不能修改常量存儲屬性
//p2.card = "333" Error!
/*
結構體和類常量與存儲屬性的關系
結構體和枚舉是值類型
類是引用類型
*/
struct Person3 {
var name: String
var age : Int
}
let p3 = Person3(name: "hjq", age: 26)
// 1.因為結構體是值類型, 所以不能修改結構體常量中的屬性;
// 2.不能修改結構體 / 枚舉常量對象中的值, 因為他指向的對象是一個常量;
//p3.name = "hiName" Error!
//p3 = Person3(name: "hiName", age: 27) Error!
class Person4 {
var name: String = ""
var age: Int = 20
}
let p4:Person4 = Person4()
// 可以修改類中常量中的值, 因為他們指向的對象不是一個常量
p4.name = "hello xiaohange"
// 不可以修改類常量的指向
//p4 = Person4() Error!
/*
延遲存儲屬性
Swift語言中所有的存儲屬性必須有初始值, 也就是當構造完一個對象後, 對象中所有的存儲屬性必須有初始值, 但是也有例外, 其中延遲存儲屬性可以將屬性的初始化推遲到該屬性第一次被調用的時候
懶加載應用場景:
1.有可能不會用到
2.依賴於其它值
*/
class Line {
var start:Double = 0.0
var end:Double = 0.0
// 1.如果不是 lazy屬性, 定義的時候對象還沒有初始化, 所以不能訪問self;
// 2.如果加上 lazy, 代表使用時才會加載, 也就是使用到length屬性時才會調用self;
// 3.而訪問一個類的屬性必須通過對象方法, 所以訪問時對象已經初始化完成了, 可以使用self
lazy var length: Double = self.getLength()
// 通過閉包懶加載
lazy var container: Array<AnyObject> = {
print("懶加載")
var arrrM:Array<Int> = []
// return self.end - self.start Error!
return arrrM as [AnyObject]
}()
func getLength() -> Double
{
print("懶加載")
return end - start
}
}
var line = Line()
line.end = 200.0
//print(line.length()) Error!
print("創建對象完畢")
print(line.length)
var arrM = line.container
arrM.append("1" as AnyObject)
arrM.append(5 as AnyObject)
print(arrM) // [1, 2, 3, 1, 5]
/*
計算屬性
1.Swift中的計算屬性不直接存儲值, 跟存儲屬性不同, 沒有任何的"後端存儲與之對應"
2.計算屬性用於計算, 可以實現setter和getter這兩種計算方法
3.枚舉不可以有存儲屬性, 但是允許有計算屬性
setter 對象.屬性 = 值
getter var value = 對象.屬性
*/
struct Rect {
var origion:(x: Double, y: Double) = (0, 0)
var size:(w: Double, h: Double) = (0, 0)
// 由於center的值是通過起點和寬高計算出來的, 所以沒有必要提供一個存儲屬性
var center:(x: Double, y:Double){
get{
return (origion.x + size.w/2, origion.y + size.h/2)
}
set{
// 註意: 計算屬性不具備存儲功能, 所以不能給計算屬性賦值, 如果賦值會發生運行時錯誤
// 註意: setter可以自己傳遞一個參數, 也可以使用系統默認的參數newValue
// 如果要使用系統自帶的參數, 必須刪除自定義參數
origion.x = newValue.x - size.w / 2
origion.y = newValue.y - size.h / 2
}
}
}
var r = Rect()
r.origion = (0, 0)
r.size = (100, 100)
//r.center = ((r.origion.x + r.size.w) / 2, (r.origion.y + r.size.h) / 2) // 可以直接在結構體中獲得, 此處可以省略
print("center.x = \(r.center.x) , center.y = \(r.center.y)")
r.center = (100, 100)
print("origion.x = \(r.origion.x) , origion.y = \(r.origion.y)")
print("center.x = \(r.center.x) , center.y = \(r.center.y)")
/*
只讀計算屬性
對應OC中的readonly屬性, 所謂的只讀屬性就是只提供了getter方法, 沒有提供setter方法
*/
class Line2 {
var start: Double = 0.0
var end: Double = 0.0
// 只讀屬性, 只讀屬性必須是變量var, 不能是常量let
// 比如想獲取length, 只能通過計算獲得, 而不需要外界設置, 可以設置為只讀計算屬性
var leghth: Double {
//只讀屬性可以省略get{}
// get{
return end - start
// }
}
}
var line2 = Line()
line2.end = 100
print(line2.length)
/*
屬性觀察器,類似OC中的KVO, 可以用於監聽屬性什麽時候被修改, 只有屬性被修改才會調用
有兩種屬性觀察器:
1.willSet, 在設置新值之前調用
2.didSet, 在設置新值之後調用
可以直接為除計算屬性和lazy屬性之外的存儲屬性添加屬性觀察器, 但是可以在繼承類中為父類的計算屬性提供屬性觀察器
因為在計算屬性中也可以監聽到屬性的改變, 所以給計算屬性添加屬性觀察器沒有任何意義
*/
class Line3{
var start: Double = 0.0{
willSet{
print("willSet newValue = \(newValue)")
}
didSet{
print("didSet oldValue = \(oldValue)")
}
}
var end: Double = 0.0
}
var l = Line3()
l.start = 10.0
/*
類屬性
在結構體和枚舉中用static
在類中使用class, 並且類中不允許將存儲屬性設置為類屬性
*/
struct Person5 {
//普通的屬性是每個對象的一份
var name: String = "hjq"
//類屬性是素有對象共用一份
static var gender: String = "Man"
static var age: Int{
return 25
}
func show()
{
print("gender = \(Person5.gender) name = \(name)")
}
}
var p5 = Person5()
//print("gender = \(p5.gender)") Error!
Person5.gender = "women"
print("p5 gender = \(Person5.gender)")
var p6 = Person5()
// 類屬性是所有對象共用一份
print("p6 gender = \(Person5.gender)")
p5.show()
//可以將計算屬性設置為類屬性
print("age = \(Person5.age)")
class Person6 {
//普通的屬性是每個對象一份
var name: String = "hjq"
//類中不允許將存儲屬性定義為類屬性
// class var gender: String = "man" Error!
//類中只能將計算屬性定義為類屬性
class var age: Int {
return 26
}
func show() {
print("age = \(Person6.age)")
}
}
var p7 = Person6()
print("p7 age = \(Person6.age)")
p7.show()
類屬性