1 import Foundation 2 /* 3 和類很相似 4 5 結構體 -> 封裝 6 屬性、方法 7 結構體是值類型 8 */ 9 10 //定義一個LSQ類型的結構體 關鍵字struct 11 struct LSQ { 12 var Name: String = "" 13 var Age: Int = 1 14 } 15 struct LSQ1 { 16 var Name: String 17 var Age: Int 18 } 19 struct LSQ2 { 20 var Name: String 21 var Age: Int=1 22 } 23 24 //結構體實例和屬性訪問 25 //聲明一個變量 26 var liu : LSQ = LSQ() 27 var liu1 : LSQ1 = LSQ1(Name: "liuq", Age: 18) 28 liu.Age=19 29 liu.Name="zhong" 30 31 liu1.Name="ha" 32 liu1.Age=20 33 34 println(liu1.Name) 35 println(liu.Name) 36 var liu2 : LSQ2 = LSQ2(Name:"AA",Age:1) 37 println("\(liu2.Age):\(liu2.Name)") 38 39 //定義帶有函數的結構體 40 struct m_lsq_1 { 41 42 var Name : String = "" 43 var Age : Int = 1 44 func getName() -> String { 45 return Name 46 } 47 } 48 49 var temp1 = m_lsq_1(Name: "王建國", Age:30) 50 println(temp1.getName()) 51 52 53 //結構體是值類型 不是引用類型 54 var temp2=temp1 55 println(temp2.getName()) 56 temp2.Name="TempName" 57 println(temp2.getName()) 58 59 60 61 /* 62 類 63 屬性、方法 64 類是引用類型 65 66 class 類名 { 67 成員變量 68 成員方法 69 } 70 */ 71 //定義一個類 72 class m_class_1 { 73 func m_class_1() { 74 Name="m_Name" 75 Age=1 76 } 77 var Name : String = "" 78 var Age : Int = 0 79 } 80 //引用類型 81 var class_1 = m_class_1() 82 83 println(class_1) 84 85 var class_2 = class_1 86 87 println(class_2) 88 89 //當需要判斷多個常量或變量是否是同一個實例時 用 === 恆等於 !== 不等於 判斷 90 if class_1 === class_2 { 91 println("相同") 92 } 93 94 /* 95 常量 結構體、枚舉 是值類型, 常量不可修改,其屬性不可修改 96 常量 類類型,是引用類型,常量不可修改,其屬性可以修改 97 */ 98 //存儲屬性 99 //結構體存儲屬性 100 struct person { 101 var name : String //變量存儲屬性 102 let sex : String = "男" //常量存儲屬性 103 } 104 105 var m_p = person(name: "lsq", sex: "男") 106 //常量屬性不可修改 107 println(m_p.sex) 108 let m_p_1 = person(name: "t", sex: "n") 109 //m_p_1.name="lsq" // m_p_1是一個常量,其屬性不可修改 110 111 //類存儲屬性 112 class c_person { 113 var name : String = "" //變量存儲屬性 114 let sex : String = "男" //常量存儲屬性 115 } 116 let c_p = c_person() //c_p 是一個常量,其屬性可修改 117 c_p.name="lsq" 118 println(c_p.name) 119 120 let c_p1 = c_person() 121 // c_p = c_p1 //類常量不可修改 122 123 //延遲存儲屬性 124 //swift中所有的存儲屬性必須有初始值,也就是當構造完一個類或結構體對象後,對象中所有的存儲屬性必須有初始值,但有例外,其中延遲存儲屬性可以將屬性的初始化向後推遲到該屬性第一次使用時賦值 關鍵字lazy 125 //使用延遲屬性:1.屬性不適合一開始就初始化,取決於外部對很多因素 2.屬性有可能從來都不用,但是它對初始化會需要很長時間 126 //學生結構體 127 struct student { 128 var name : String 129 var age : Int 130 func get_name() { 131 println("我的姓名是:\(name)") 132 } 133 } 134 //班級類 135 class my_class { 136 var members : [student] = [] 137 lazy var score : Double = self.getScore() //延遲屬性 lazy關鍵字 score的值是 getScore()結果 當訪問score時纔去調用方法 138 //計算平均值 139 func getScore() -> Double { 140 var t: Double = 0 141 for i in members { 142 t += Double(i.age) 143 } 144 if members.count > 0 { 145 return t / Double(members.count) 146 } 147 return 0 148 } 149 //顯示所有name 150 func show () { 151 for i in members { 152 println(i.name) 153 } 154 } 155 func show_1() { 156 for i in members { 157 i.get_name() 158 } 159 } 160 161 } 162 //常規用法 163 var s1 = student(name: "小明", age: 8) 164 var s2 = student(name: "小紅", age: 10) 165 var c1 = my_class() 166 c1.members.append(s1) 167 c1.members.append(s2) 168 c1.show() 169 c1.show_1() 170 println(c1.getScore()) 171 172 //使用延遲屬性 173 var c2 = my_class() 174 c2.members.append(s1) 175 c2.members.append(s2) 176 println(c2.score) 177 178 179 /* 180 計算屬性 181 1.計算屬性不直接存儲其值,與存儲屬性不同,沒有任何後端存儲與之對應 182 2.計算屬性用於計算,可以實現setter和getter 兩種計算方法 183 3.枚舉不可以有存儲屬性,但是允許有計算屬性 184 對象.屬性 = 某值 setter 185 let value = 對象.屬性 getter 186 個人理解:與c#中的get set 相似,對象存放結果,每次獲取結果需要計算 187 swift中的計算屬性,不可以直接存儲任何的值。 188 189 只讀屬性 如果計算屬性只提供了get 沒有提供set那麼該屬性是隻讀屬性 190 */ 191 192 struct m_rect { 193 var origion: (x: Double,y: Double) = (0,0) 194 var size: (w: Double,h: Double) = (0,0) 195 //size是計算屬性,不能直接賦值, 196 var center : (x: Double,y: Double) { 197 get { 198 //獲取的值是重新計算的 199 return (origion.x + size.w/2 , origion.y + size.h/2) 200 } 201 set(n) { 202 //賦值的時候直接給 origion賦值 203 origion.x = n.x - size.w/2 204 origion.y = n.y - size.h/2 205 //origion.x = n.0 - size.w/2 206 //origion.y = n.1 - size.h/2 207 } 208 /* 209 當不指定n的時候,默認寫法是 newValue 表示要賦的值 210 set { 211 //賦值的時候直接給 origion賦值 212 origion.x = newValue.x - size.w/2 213 origion.y = newValue.y - size.h/2 214 } 215 */ 216 } 217 } 218 219 var rect = m_rect() 220 rect.size = (100,100) 221 println(rect.origion) 222 rect.center = (12 ,23) 223 println(rect.origion) 224 225 226 /* 227 計算只讀屬性 228 如果計算屬性只提供了get 沒有提供set那麼該屬性是隻讀屬性 229 230 */ 231 //學生結構體 232 struct student_1 { 233 var name : String 234 var age : Int 235 func get_name() { 236 println("我的姓名是:\(name)") 237 } 238 } 239 //班級類 240 class my_class_1 { 241 var members : [student_1] = [] 242 lazy var score : Double = self.getsum() //延遲屬性 243 //計算屬性 只讀屬性 只提供了get方法 244 var allage : Double { 245 246 get{ 247 return getsum() 248 } 249 } 250 //只讀計算屬性的簡寫 省略 get關鍵字 251 var allages : Double { 252 return getsum() 253 } 254 func getsum() -> Double { 255 var t: Double = 0 256 for i in members { 257 t += Double(i.age) 258 } 259 return t 260 } 261 262 } 263 var c3 = my_class_1() 264 c3.members.append(student_1(name: "小明", age: 8)) 265 c3.members.append(student_1(name: "小紅", age: 10)) 266 println(c3.allage) 267 268 269 /* 270 屬性觀察器 271 當類中的屬性或方法的某個值發生了變化,則調用指定的方法 在OC中稱之爲KVO 272 willSet 修改前被調用 273 didSet 屬性被修改之後調用 274 相當於註冊了兩個事件 275 276 */ 277 class my_class_3 { 278 var t_value : Double = 0{ 279 willSet { 280 println("WillSet調用:\(newValue)") 281 } 282 didSet { 283 println("didSet調用:\(oldValue)") 284 } 285 } 286 287 } 288 var m_3 = my_class_3() 289 m_3.t_value = 1 290 291 //類型屬性 可以理解爲靜態變量 292 //在結構體中用static關鍵字修飾 在class類中用class關鍵字修飾 293 struct type_property { 294 var property : Int = 0 295 //類型屬性, 該變量屬於當前類的 ,與其他語言中的靜態變量相似 不同的是訪問該變量時 只能通過類名.出該變量 所有實例化該類的對象共用此變量 296 static var static_property : Int = 0 297 } 298 var obj = type_property() 299 obj.property = 10 300 type_property.static_property = 10