(未 经 博 主 同 意,不 得 转 载 !)
------------------------华丽分割线-----------------------
1 // 2 // main.swift 3 // SwiftDemo3 4 // 5 // Created by lanouhn on 15/11/11. 6 // Copyright © 2015年 刘勇虎. All rights reserved. 7 // 8 9 import Foundation 10 11 12 //MARK: ---属性--- 13 //MARK:从功能分为两种 14 //1.存储属性: 2.计算属性 15 //MARK:从调用对象分两种: 16 //1.类属性 2.实例属性 17 18 19 20 //1.存储属性:类似于OC中的实例变量.用来接受我们设置的属性值 21 class Animal { 22 // <#properties and methods#> 23 // 定义一个存储属性 24 var animalName :String = "小熊维尼" 25 // 定义可选类型 26 var isFly :Bool? 27 // lazyLoad,只有用的时候才会执行 28 lazy var isSpeak :Bool = true ;// lazy var isSpeak = true; 类型在赋值时可省略 29 30 } 31 32 33 //实例化一个对象 34 let animal = Animal()//相当于OC中默认init ,也可以在类中重写init,调用时一般存在参数 35 36 //设置属性 37 animal.animalName = "跳跳虎" 38 39 animal.isFly = false 40 41 animal.isSpeak = true 42 43 //访问属性 44 //print("\(animal.animalName) 说话\(animal.isSpeak) 飞\(animal.isFly)") 45 //print("\(animal.animalName) 说话\(animal.isSpeak) 飞\(animal.isFly!)") 46 47 //MARK:2.计算属性:类似OC中的属性。(与实例变量最大区别:有set和get方法,直接访问方法 (KVC间接访问)) 48 49 class Animals { 50 // 存储属性 51 var animalName :String = "拍拍熊" 52 // 计算属性 53 var aName :String{ 54 get{ 55 56 print("get") 57 58 return "喜欢\(animalName)的人都有一个不同的心"//如果直接写return,而没有写set方法即代表这个属性是只读属性,在后边调用中set方法会报红 59 }set{ 60 print("set") 61 animalName = newValue//newValue 就是我们在外边等号后想要赋上的值, 62 // MARK:注意 定义属性最好不要使用newXXX容易和系统重名 63 64 } 65 66 } 67 } 68 69 70 //实例化调用 71 let animal2 = Animals() 72 73 animal2.animalName = "安妮熊" 74 //调用计算属性的get方法 75 //print(animal2.aName) 76 77 //调用计算属性的set方法 78 79 //animal2.aName = "金克斯" 80 81 82 83 //MARK:--属性观察器-- 84 class iPhone{ 85 //定义一个存储属性 86 var iPhoneType = "6sPlus" 87 var iPhoneColor = "RoseColor" 88 // 属性观察器 ,观察属性变化 89 var iPhonePrice :Int = 6000 { 90 willSet{ 91 print("newValue = \(newValue)") 92 }didSet{ 93 print("oldValue = \(oldValue)") 94 95 } 96 97 } 98 99 } 100 101 102 //实例化一个对象,调用set 103 104 let tempiPone = iPhone() 105 106 //tempiPone.iPhonePrice = 666//会调用willSet 和 didSet 107 108 109 110 //(1)类 的 类属性 111 class Animal3 { 112 // 类属性只能是计算属性 113 class var animal3Name : String { 114 return "哆啦A梦" 115 } 116 117 } 118 119 //调用类属性 (直接用类调用,类似OC中类方法) 120 //print(Animal3.animal3Name) 121 //Animal3.animal3Name = "九尾"//只有return,属性为只读,不管是var、还是let修饰 122 123 124 //(2)结构体的类属性 关键字 static 125 struct Animal4 { 126 127 // 类属性 计算属性 128 static var animal4Name :String { 129 return "米老鼠---米奇" 130 } 131 132 133 // 类属性 存储属性 134 static var animal4Friend = "唐老鸭 -- 唐纳德" 135 } 136 137 //MARK:注意-结构体的类属性不仅可以是计算属性,也可以是存储属性(类中的类属性不能是存储属性) 138 139 //调用属性,直接用结构体调用 140 141 //print(Animal4.animal4Name) 142 143 //Animal4.animal4Name = "唐老鸭"//只有return,属性为只读,不管是var、还是let修饰 144 145 //print(Animal4.animal4Friend) 146 147 148 //MARK: ---属性 方法 函数 --- 149 150 // 1.类方法(+) 151 //2.实例方法(-) 152 153 class CityInfo { 154 var cityName = "" 155 var citytravelPoint = "" 156 157 // 实例方法 158 func printCityTravelPoint(){ 159 160 print("\(cityName)的景点有\(citytravelPoint)") 161 } 162 163 // 类方法 164 class func printCityTravelPoint2(cityName:String,citytravelPoint:String) { 165 print("\(cityName)的景点有\(citytravelPoint)") 166 } 167 } 168 169 170 //调用 171 172 let beiJing = CityInfo() 173 174 beiJing.cityName = "北京" 175 beiJing.citytravelPoint = "天安门" 176 //用实例化的方法去调用实例方法 177 //beiJing.printCityTravelPoint() 178 //调用类方法(直接用类调用) 179 //CityInfo.printCityTravelPoint2("中关村", citytravelPoint: "Lenvo") 180 181 //注意事项 182 struct CityInfo2 { 183 var cityName = "北京" 184 var citytravelPoint = "故宫" 185 // 实例方法 186 mutating func printCityTravelPoint(){ 187 //MARK:注意- 结构体的方法中修改属性 ,需要在func 前用 mutating 标记 ,而类中的方法中修改属性,不需标记 188 self.citytravelPoint = "天坛" 189 190 print("北京有\(citytravelPoint)")// print("北京有\(self.citytravelPoint)") 191 } 192 193 // 194 } 195 196 197 //调用:修改属性需要将实例变量设为var 198 var cityInfo2 = CityInfo2() 199 200 201 cityInfo2.citytravelPoint = "颐和园" 202 203 //cityInfo2.printCityTravelPoint() 204 205 206 207 208 209 //MARK: ---类的继承--- 210 //继承:可以使用父类属性并且实现、重写父类方法 211 //只有类可以,结构体是不能继承的 212 //如果没有明显的继承关系,那么就是继承于基类 213 /*MARK:注意事项---防止重写--- 214 1.在属性或者方法名前加final关键字,那么子类能继承,不能重写 215 2.如果在类前加final这个类不能被继承 216 */ 217 218 class Zombie { 219 // 存储属性 220 var blood :Int = 10; 221 // 计算属性 222 223 // final var name:String {//MARK:-关键字final:保护该属性或方法使得子类无法重写该方法 224 var name:String { 225 // 只读 226 return "普通僵尸" 227 } 228 // 实例方法 229 func printZombie(){ 230 print("我是父类僵尸") 231 } 232 } 233 234 // 定义僵尸的子类 235 class PailZombie :Zombie{ 236 //增加属性 237 var tool :String = "pail" 238 // 增加一个新方法 239 func printTool(){//(1) 240 print("我的工具是\(self.tool)") 241 } 242 // 重写父类方法 关键字:override 243 override func printZombie() {//(2) 244 print("子类重写父类方法") 245 } 246 // 重写父类的计算属性 247 override var name:String{//(3) 248 return "我是铁桶僵尸" 249 } 250 } 251 252 //实例化一个铁桶僵尸 253 var pailZombie = PailZombie() 254 pailZombie.tool = "工具是铁通" 255 //print(pailZombie.tool) 256 257 //设置和访问父类属性 258 pailZombie.blood = 30 259 260 //print("pailZonmbie的血量:\(pailZombie.blood) 名称:\(pailZombie.name)") 261 262 //使用自身独有方法 263 //pailZombie.printTool()//(1) 264 //使用父类方法 265 //pailZombie.printZombie()//(2) 266 267 //调用重写后的父类只读计算属性 268 //print(pailZombie.name)//(3) 269 270 271 //MARK: ---构造方法(构造函数)--- 272 class Food { 273 var foodName:String 274 var foodType:String 275 var foodPrice:Double 276 // 定制构造方法 set 方法 277 init(foodName:String , foodType:String,foodPrice:Double){ 278 // 完成属性赋值 279 self.foodName = foodName 280 self.foodType = foodType 281 self.foodPrice = foodPrice 282 } 283 } 284 285 //实例化一个food对象 286 let food = Food(foodName: "苹果", foodType: "水果", foodPrice: 2.0) 287 288 //print("foodName:\(food.foodName)") 289 290 291 292 293 //子类要继承父类 294 class Apple:Food{ 295 //苹果的类型,新增属性 296 var appleType:String 297 // 重写父类构造方法 298 init(foodName: String, foodType: String, foodPrice: Double ,appleType:String) { 299 300 // 完成属性赋值 首先给自己独有属性赋值, 301 self.appleType = appleType 302 // 直接调用父类构造方法 然后调用父类构造方法 303 super.init(foodName: foodName, foodType: foodType, foodPrice: foodPrice) 304 305 } 306 } 307 308 //实例化一个对象(实例化一个苹果) 309 let apple = Apple(foodName: "苹果", foodType:"水果" , foodPrice: 6.6, appleType: "红粉佳人") 310 311 print(apple.foodName) 312 313 314 /*总结一下 315 1.构造方法的安全性: 316 (1)构造方法完成后,创建出来的实例对象的属性必须有值 317 (2)当我们继承了父类的构造方法后,需要先对自身独有的属性赋值,然后在调用父类的构造方法 318 319 320 */ 321 322 323 //MARK: ---内存--- 324 //引用计数 325 class runSun { 326 //属性 327 var personName:String 328 // 构造方法 329 init(personName:String){ 330 self.personName = personName 331 print("\(personName)变身成功") 332 } 333 334 // 追逐太阳 335 func runSunAction (){ 336 print("\(personName)正在追逐太阳!!!") 337 } 338 //MARK: 析构方法(类似OC中的dealloc) 339 deinit { 340 print("\(self.personName)扑街!!!") 341 } 342 } 343 344 345 //创建一个追太阳的人,引用计数 + 1 (0 -> 1) 346 var runSunPerson :runSun? = runSun(personName: "夸父")//? 使可选,以便置为nil 347 348 //再创建一个 引用计数 + 1 (1 -> 2) //MARK:注意 : --在原基础上,虚拟内存地址引用计数 +1 349 var runPerson :runSun? = runSunPerson 350 351 352 //调用方法 353 runSunPerson!.runSunAction()//因为是可选类型需要强制转换 354 355 //释放 :引用计数 - 1 (2->1) ,内存没有释放 356 runSunPerson = nil //MARK:注意 : --在原基础上,虚拟内存地址引用计数 -1 357 //再次调用 358 runPerson!.runSunAction() 359 //释放 :引用计数 - 1 (1->0) ,内存释放 360 runPerson = nil 361 362 363 //MARK: --- 总结 --- 364 /*野指针:指针指向无效空间 内存泄露:空间没有被释放或者没有被及时释放 365 1.swift使用的是引用计数管理机制。当这个对象不再使用的时候,就会执行deinit方法,销毁该空间 366 2.swift中当有一个指针指向该空间时,该空间就不会被释放。只有没有指针指向该空间时,这个空间才会被释放(引用计数为0) 367 */ 368 369 370 //MARK:---循环引用 weak可以破坏引用循环--- 371 //弱引用:使指向引用计数不增加,关键字:weak 如果不写,默认strong,strong是强引用,会使得引用计数 + 1 ,weak是弱引用,引用计数不会增加 372 373 class Person { 374 var room :Room? 375 var personName:String 376 377 378 // 构造方法 379 init(personName:String){ 380 381 self.personName = personName 382 } 383 384 385 deinit{ 386 print("该用户扑街 !!") 387 } 388 389 } 390 391 class Room { 392 // 属性 393 var roomNumber :Int 394 395 // 因为有得房间可以没有人,所以用可选类型 396 weak var person:Person?//不赋初值、不是可选类型或者没写初始化方法(init),会报错 弱引用:使指向引用计数不增加,关键字:weak 如果不写,默认strong,strong是强引用,会使得引用计数 + 1 ,weak是弱引用,引用计数不会增加 397 deinit{ 398 print("房子被销毁 !!") 399 } 400 401 init(roomNumber:Int){ 402 self.roomNumber = roomNumber 403 } 404 } 405 406 //实例化对象 407 var personItem :Person? = Person(personName: "王大锤") 408 409 var roomItem :Room? = Room(roomNumber: 250) 410 411 412 //给大锤开个房 413 414 personItem!.room = roomItem 415 416 //给房间设置主人 417 roomItem!.person = personItem 418 419 420 421 personItem = nil 422 roomItem = nil