[Swift]类(Class)——属性
来源:互联网 发布:vr设备 知乎 编辑:程序博客网 时间:2024/05/20 15:42
在Swift语言中,提供了全面的面向对象的支持。首先支持类定义,类中可以定义各种类型的方法和属性,可以通过设置访问修饰符来控制哪些成员和方法是对外界可见的,哪些是不可见的,实现对类的封装。
同时也可以继承一个类或者多个类,实现类的继承性。还有一个叫协议的概念,等同于别的编程语言中的接口。协议与类有相同也有不同。
- 相同之处:都是可以继承扩展的,协议本身也可以继承别的协议。
- 不同之处:协议不支持属性,方法也只能声明,不实现。协议独立来看,也不能实例化成某个对象。也就是说,协议需要某个具体的类去继承,这叫实现协议。实现协议之后,就叫某个类遵守或者符合某个协议。
一、编写第一个类
类是某一类事物的抽象,通过抽象定义了一件事物的特点,通常来说,类定义了事物的属性和行为。从程序上讲,类时生成将来所要用的具体对象的代码模板。
class Person { //类型属性、方法}/*在Swift语言中,Person类的声明和其他语言一样,以关键字class声明,类的名称首字母一般建议大写,它可以是任意数字、字母、下划线组合,不过不能以数字开头。*/
尽管其主体是空的,没有任何实际的用处,我们已经完成了类的最简单的定义,定义一个类,定义了一种新的数据类型,这种类我们叫做空类,空类也是可以被调用的。
var p = Person()println(p)
上面代码中,P就是对象,是Person类的具体化,类是对象的模板,定义一个类,可以生成无数个对象。生成对象的过程叫类的实例化
1、属性
属性就是类所表示的现实对象的特性在代码中的反映,比如现实中有学生这个身份类别,学长的属性有姓名、班级、籍贯,把相应的内容对应到类代码即可:
class Student{ var name:String = "" var classno:Int = 0 var from:String = ""}
class Student{ var name:String = "" //变量属性 var classno:Int = 0 var from:String = "" let country:String = "中国" //常量属性}var student = Student()student.name = "HTX"student.classno = 1student.from = "NanTong"println("\(student.name) \(student.classno) \(student.from)")//输出:HTX 1 NanTong
在Swift语言中,属性的类型可以分为两种:存储属性和计算属性
存储属性就是用来表示类的一个特性。计算数学本身并不直接存储特性,提供的是一个计算后的结果。
1.1、存储属性
正如变量一样,属性也分为变量属性和常量属性,都叫存储属性,并且也分别用关键字var 和关键字let来描述。
上例中得name、classno、from就是变量属性,而country则是常量属性。
以下三个注意事项:
(1)存储属性在定义时,需要为每一个属性定义一个默认值,当然也可以在初始化的时候设置属性的初始值。如果初始化也不定义默认值,在调用super.init()时会出错,或者在声明了对象之后,也无法为此变量赋值,除非明确定义为强制解包可选。
强制解包可选:
class StudentOptional{ var name:String! var classno:Int! var from:String! let country:String!}var studentOptional = StudentOptional()studentOptional.name = "HTX"studentOptional.classno = 2studentOptional.from = "RuGao"
(2)还有一个需要注意的地方就是存储属性中的常量属性,常量属性并不意味着绝对不能变化,而是要看情况,如果存储属性的常量属性是值类型,比如字符串、结构体,就不能再变,结构体的属性也不能再变。如果是类,那么就可能重新赋值。
class Person{ var name:String!}class StudentOptional{ var name:String! var classno:Int! var from:String! let country:String = "china" let friend:Person = Person()}var studentOptional = StudentOptional()studentOptional.name = "HTX"studentOptional.classno = 2studentOptional.from = "RuGao"//下面这行会出错//studentOptional.country = "中国"//下面这一行就不会出错studentOptional.friend.name = "HeTianXiong"
(3)之前说到,存储属性一般情况下要求初始化,我们可以设置一个lazy修饰符,使得这种初始化延迟,尽管我们在属性声明时已经做了这种初始化上的定义。所谓修饰符就是加缀在变量、函数、类等得定义前面,用来约束或者增强变量、函数、类功能的一种特殊关键字。
lazy修饰的存储属性,叫懒惰储存属性。懒惰存储属性是当它第一次被使用时才进行初值计算。比如当属性初始值因为外部原因在实例初始化完成之前不能确定时,就要定义成懒惰存储属性。当属性初始值需要复杂或高代价的设置,在它需要时才被赋值时,懒惰属性就派上用场了。
class Deposit{ init(){ println("init at deposit") }}class PersonLazy { var name:String! lazy var money:Deposit = Deposit()}class StudentLazy{ var name:String! var classno:Int! var from:String! let country:String = "china" let friend:PersonLazy = PersonLazy()}var studentlazy = StudentLazy()studentlazy.name = "HTX"studentlazy.classno = 1studentlazy.from = "suzhou"studentlazy.friend.name = "huhu"
此类定义了一个lazy属性,所以”init at deposit”根本不会输出,因为在本例中没有用到,就没有赋值计算,如果没有lazy的修饰,这句话就会在上面的代码所有输出之前中输出。
懒惰属性必须时变量属性,这个很容易理解,因为它的初始值直到实例初始化完成后,在调用时才被计算,常量属性在实例初始化完成之前就应该被赋值,因此常量属性不能被声明为懒惰属性。
1.2、计算属性
计算属性在别的编程语言中一般以成员函数或者方法的形式出现的。当然在Swift中也可以使用方法,不过提供一种更为灵活的选择。
计算属性并不能直接地保存数据,但是可以用getter和setter来间接地获得或者改变其他属性和值
首先我们做一个简单的计算器:
1、用方法来实现
class Calculator { var a:Int = 1 var b:Int = 1 init(a:Int,b:Int){ self.a = a self.b = b } func sum()->Int { return a + b } func quotient()->Int{ return a/b } func product()->Int{ return a * b } func difference()->Int { return a - b }}
2、使用计算方式实现:
class PCalculator { var a:Int = 1 var b:Int = 1 var sum:Int{ return a + b } var difference:Int{ return a - b } var product:Int{ return a * b } var quotient:Int { return a/b } init(a:Int,b:Int){ self.a = a self.b = b } }
虽然计算属性并不直接的保存变量值,但是可以通过对其值得设置来改变别的属性值,只有比较方便,在前面的实例基础上加一个scale计算属性,scale本身无须存储,它是用于等比扩大两个值的。当然其他计算属性的值也要跟着变化。
class PCalculator { var a:Int = 1 var b:Int = 1 var sum:Int{ return a + b } var difference:Int{ return a - b } var product:Int{ return a * b } var quotient:Int { return a/b } init(a:Int,b:Int){ self.a = a self.b = b } var scale:Int{ get{ return a/a } set{ a = a * newValue b = b * newValue } }}var pcal = PCalculator(a: 30, b: 10)pcal.scale = 3println("\(pcal.sum) \(pcal.quotient) \(pcal.product) \(pcal.difference)")//输出:120 3 2700 60
有关计算属性,有两个注意事项:
- 1、计算属性(包含只读计算属性)都应该使用var关键字,因为他们的值并不是固定的。let关键字只被常量属性使用,若用let定义计算属性,编译器会报错。
- 2、使用计算属性一定要声明类型,否则报错。
1.3、属性观察者
属性观察者,个人理解更像是触发器,在数据库中就有触发器的概念,当一个操作发生时,触发另一个预置好的操作,也有点像回调函数,当某一个事件触发之前或者之后调用。
不过属性观察者同触发器不同的是,还可以在属性变更之前触发!属性观察者观察属性值的改变并对此作出响应。当设置属性的值时,属性观察者就被调用,即使当新值同原值相同时也会被调用。除了懒惰存储属性,你可以为任何存储属性加上属性观察者定义。另外,通过重写子类型属性,也可以继承属性(存储或计算)加上属性观察者定义。
在2048游戏中,就用到了属性观察者定义,具体是在积分面板上,玩游戏时,变更的是分数,但是积分面板不仅仅有分数,还有其他文字,甚至有两种积分——普通分和最高分,每一次变更分数时,面板的数字也会跟着改变。
var label:UILabel!var stype:String! //显示最高分还是分数var score:Int = 0{ didSet{ //分数变化,标签内容也变化 label.text = "\(stype):\(score)" }}
属性观察者也是过去类行为的优化。在别的语言中,上面代码可能如下所示:
var label:UILabel!var stype:String! //显示最高分还是分数var score:Int = 0func setScore(score:Int){ didSet{ self.score = score //分数变化,标签内容也变化 label.text = "\(self.stype):\(self.score)" }}
上述代码专门为score设计了 setter函数,在每一次赋值的时候,关联更新标签上的文本,这样带来不好的地方,将属性更新和其他界面表现操作耦合在一起,可见使用属性观察者更加简洁。
对于属性观察者,有如下需要注意点:
- 1、给属性添加观察者必须要声明清楚属性类型,否则编译器报错
- 2、willSet可以带一个newName的参数,如果不这样的话,正如计算属性中医院买这个参数就被默认位newValue。
- 3、didSet也可以待一个oldName的参数,表示旧的属性,如果不带,这个参数就被默认命名为oldValue。
- 4、属性初始化时,willSet和didSet并不会调用,只有在初始化上下文之外,当设置属性时才被调用
- 5、willSer和didSet每次设置属性值都会被调用,即使设置的值与原来的相同。
var stype:String! //显示最高分还是分数var score:Int = 0{ willSet{ //分数变化,标签内容也变化 label.text = "\(stype):\(newValue)" }}
1.4、类型属性
实例属性是特定类实例的属性。当创建一个类实例时,这个实例有自己的属性值的集合,这将它与其他实例区分开,每一个类实例都有自己的存储空间,这些实例的属性也有自己专门的存储空间。
但是也可以定义一种属性,这种属性不属于任何一个类的实例,即不属于任何一个对象。即使创建再多这个类的实例,这个属性也不属于任何一个,它只属于类本身,这样的属性称为类型属性。类型属性在别的语言中叫做类静态变量。
类型属性有点像全局变量,可以在定义后直接使用,不过全局变量不依赖于任何类而存在,类型属性则依赖于某一个类而存在,所以在调用时,需要增加类前缀,并受限于该类型属性在类的访问层级。
类型属性定义的方法很简单,我们在类中定义时,直接在变量关键字var前加上class关键字,同时要用get函数的设置的方法返回变量的值,而不能直接赋值。
class Teacher { var name:String! var classno:Int! var from:String! class var country:String{ return "中国" }}println(Teacher.country)//输出:中国
===========================================================
篇幅略长,类的方法在下一篇文章。
- [Swift]类(Class)——属性
- Swift——类的基本属性
- 属性—Swift学习笔记(十三)
- swift 笔记 (十) —— 属性 (类,结构体,枚举)
- Swift学习笔记系列——(9)属性
- Swift学习笔记10——属性(Properties)
- Swift学习笔记(15)——属性
- iOS开发Swift篇—(九)属性
- Swift——(一)为Swift内置类型添加属性
- [翻译]Swift编程语言——属性
- Swift学习笔记—— 属性
- swift学习日志—— 属性
- swift学习日志—— 属性观察
- 20、swift开发iOS——属性
- Swift——监听属性的改变
- Swift类属性
- Swift 类与属性
- Swift类属性定义
- 编译hadoop
- 互联网思维:一切以用户为中心
- 二叉树的一维数组存储
- Android详细的对话框AlertDialog.Builder使用方法
- 如何只复制一个表结构
- [Swift]类(Class)——属性
- windows分页管理机制
- 异步通知:FASYNC
- 【翻译】Ext JS 6有什么新东西?
- 蓝桥杯 概率计算
- 【贪心】POJ 1065
- elasticseach日常维护之shard管理
- 使用_CrtSetDbgFlag检测内存泄露
- 线程池python实现