Swif基本语法以及与OC比较三

     (未 经 博 主 同 意,不 得 转 载 !)

 
------------------------华丽分割线-----------------------

 

 

  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

 

posted @ 2015-11-12 22:56  抠得儿  阅读(290)  评论(0编辑  收藏  举报