Swfit入门教程9-类和结构体
发布时间:2020-12-15 17:33:48 所属栏目:百科 来源:网络整理
导读:原创blog,转载请注明出处 http://blog.csdn.net/hello_hwc 之所以把这两个放在一起,是因为在swfit中,类和结构体的关系非常紧密,甚至很多时候很难区分是用类实现还是用结构体实现好。 在其他语言中,类对应对象,而在swfit中,常常称作类对应实例,结构体
原创blog,转载请注明出处 http://blog.csdn.net/hello_hwc 之所以把这两个放在一起,是因为在swfit中,类和结构体的关系非常紧密,甚至很多时候很难区分是用类实现还是用结构体实现好。 在其他语言中,类对应对象,而在swfit中,常常称作类对应实例,结构体也对应实例。一、类和结构体的异同 1、都可以定义属性存储值 2、都可以定义方法提供功能 3、都可以定义构造函数 4、都可以定义附属脚本 5、都支持扩展和协议 相对于结构体,类具有如下功能 1、类允许继承 2、类允许动态类型检查 3、类允许析构器释放资源 有一点要始终记住,类传的是引用,结构体传的是值,也就是copy; 以下情况比较适合使用结构体 1、应用在存储和传递少量相关数据,并且传递值,而不是引用;(大部分情况下考虑的是这一点) 2、不需要继承 二、类和结构体简析 定义 class HwcClass{ var classVariable = 0 func print(){ println("From class") } } struct HwcStruct{ var structVariable = 1 func print(){ println("From struct") } } 这里要养成一个命名习惯,类名的开头用大写字母,属性和方法的开头字母用小写 然后按照每个单词首字母大写:例如:var firstVariable 声明完类之后,用构造器创建实例 var someHwcClassInstance = HwcClass() var someHwcStructInstance = HwcStruct()用点(.)来访问类或者结构体的属性和方法 var classVariable = someHwcClassInstance.classVariable var structVariable = someHwcStructInstance.structVariable someHwcClassInstance.print() someHwcStructInstance.print()这里要提到的是,与Objective-C不同,swfit允许直接修改结构体的某一个子属性,另外array 和dictionary内部都是结构体实现的,所以他们不属于AnyObject 判断类和结构体是否想“相等” 对于类来说,是引用类型,所以是否相等要看两个引用是否相同 swift提供===和!==盘判断是否等价于,也就是说是否是同一个引用 对于结构体来说,是值类型,所以是否相等看两个结构体内容是否相等 采用==和!=来判断 三、属性 swift中把objecti-C中的属性定义都简化成一个语句 命名 类型 内存管理特征 1、存储属性-可以在class struct中使用 用来存储值,可以是常量,可以是变量 可以在定义的时候指定初值,也可以在构造的时候赋予初值(对let类型的属性也使用) class csdnID{ var name:String = “jack” let ID:String = "123456" init(name:String,ID:String){ self.name = name; self.ID = ID } } var myID = csdnID(name:"HelloHwc",ID:"12345568") myID.name = "CallMeHwc" //myID.ID = "1234556" wrong因为,用户名可以修改,但是系统赋予给用户的识别ID不能修改,对于不想修改的,我们只需要在生命中声明为let即可,注意,及时是let,可以在构造的时候进行赋值 2、延迟属性 关键字lazy 在需要的时候才进行初始化,构造的时候无需进行初始化,但是对延迟属性要指明构造器。 适用于: (1)当属性的值需要于复杂或者大量计算时 (2)当属性值依赖于外部因素时 (3)当属性值不确定是否会被使用到时 class CSDN{ lazy lazycoder:NSMutableArray = NSMutableArray(array:["jack","lucy","tom"]) //Something else }当我们想要使用这个lazy变量的时候直接使用,因为我们不是每一次都要知道那些人lazy,所以不需要每次在构造的时候都初始化这个变量。 var instance = CSDN() var lazyCoders = instance.lazycoder 3、计算属性-可以在class struct enum中使用 计算属性在内存中并不保存属性 通过getter来获取值 可选setter来进行间接赋值 class Line{ let startPoint:Int = 0 var endPoint:Int = 15 var centerPoint:Int{ get{ return startPoint+endPoint/2 } set(newCenter){ endPoint = 2*newCenter - startPoint } } } swift中,对setter方法,可以使用默认的newValue作为传入值 class Line{ let startPoint:Int = 0 var endPoint:Int = 15 var centerPoint:Int{ get{ return startPoint+endPoint/2 } set{ endPoint = 2*newValue - startPoint } } } var line1 = Line() println(line1.endPoint) println(line1.centerPoint) line1.centerPoint = 10 println(line1.endPoint) 如果不提供set方法,则centerPoint为只读属性 class Line{ let startPoint:Int = 0 var endPoint:Int = 15 var centerPoint:Int{ get{ return startPoint+endPoint/2 } } } var line1 = Line() line1.centerPoint = 10//Wrong 4、属性观察器 属性观察器响应值得变化,每次赋值的时候(就算值没有变化),属性观察期都会被调用。但是不 包括初始化的时候。 两个观察器, willSet 在属性设置前调用;默认会将新的值作为擦书传入,如果不指定,默认为newValue didSet ?在属性已经被设置后调用;默认旧值传入,不指定的话,默认oldValue class Test{ var testVar:String = "oldvalue"{ willSet{ println("Value to be set is (newValue)") } didSet{ println("Old value is (oldValue)") } } } var instance = Test() instance.testVar = "newvalue"可以看到输出是 Value to be set is newvalue Old value is oldValue 5、类型属性-适用于struct enum 类似于C++中的static属性,就是该属性隶属于类,调用的时候直接通过类型名调用,不需要实例化。 对于struct和enum,类型属性由关键字static声明 何时使类型属性:就是本身这个属性和对象无关,比如我接下来的类型描述就与对象无关;, struct Point{ var x:Int = 0 var y:Int = 0 static var description:String = "This is a struct about Point" } println(Point.description) 四、方法 Swfit中可以为类,结构体和枚举定义方法,这也是swfit相对于objective C的改动之一 方法分为两种 实例方法:通过实例调用 类型方法:通过类名调用 关键字和类型属性一样,用static 和 class来声明 1、实例方法 调用的时候通过.来调用 其中self为实例本身,类似C++中的this指针 简单的例子 struct PersonInfo{ var name:String; var id:String; func showInformation(){ println("(name)n(id)") } } class MyCSDN{ var info:PersonInfo var visitTimes:Int init(info:PersonInfo,visitTimes:Int){ self.info = info //用self来区分 self.visitTimes = visitTimes } func showCSDNInfo(){ info.showInformation() println(visitTimes) } } var onePerson = PersonInfo(name:"hwc",id:"7865123") var myCsdn = MyCSDN(info:onePerson,visitTimes:6800) myCsdn.showCSDNInfo()可以看到输出 hwc 7865123 6800 2、局部和外部参数名称 局部参数供函数内使用 外部参数供调用的时候使用 swift默认为方法的第二个参数开始提供外部参数,如果想要第一个参数也作为外部参数,可以加上# 举例 class CSDN{ func testWithFirst(first:Int,second:Int){ println(first+second) } } var instance = CSDN() instance.testWithFirst(1,second:2)当第一个参数不提供外部参数的时候,通常会在函数名中用with,by等表明第一个参数是干嘛的 当然,我们也可以添加一个#让其作为外部参数使用,这时候名称就不需要像上面那样,指明第一个参数是做什么的 class CSDN{ func testWith(#first:Int,second:Int){ println(first+second) } } var instance = CSDN() instance.testWithFirst(first:1,second:2)3、mutating关键字 对于结构体和枚举来说,因为其都是值类型,所以一般情况下不允许实例方法修改其值。 如果确实需要修改,则可以选择mutating这个方法,在方法调用后,改动会保存在实例中。 struct Line{ var startPoint:Int = 0 var endPoint:Int = 15 mutating func changeEndPoint(newValue:Int){ endPoint = newValue } } var line = Line() line.changeEndPoint(20) println(line.endPoint)4 类型方法 对于class使用关键字class 对于struct enum使用关键字static? 举例 private var name:String = "Hello_hwc" class CSDN{ class func print(){ println(name) } } CSDN.print() ADD:由于swift语言版本更新的问题,暂时不支持在class中声明实例变量了 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |