做为一门面向对象语言,类也是Swift的很是重要的类型,咱们先来看下一个简单的类swift
//Swift中一个类能够不继承于任何其余基类,那么此类自己就是一个基类 class Person { //定义属性 var name:String var height = 0.0 //构造器方法,注意若是不编写构造方法默认会自动建立一个无参构造方法 init(name:String){ self.name = name } //析构器方法,在对象被释放时调用,相似于ObjC的dealloc,注意这里没有括号和参数,没法直接调用 deinit{ println("deinit...") } //定义对象方法 func showMessage(){ println("name=\(name),height=\(height)") } } //建立类的对象 var p = Person(name: "Liuting") p.height = 170.0 p.showMessage() //结果:name=Liuting,height=170.0 //类是引用类型 var p2 = p p2.name = "XiaoMing" println(p.name) //结果:XiaoMing //“===”表示等价于,这里不能使用等于“==”,等于用于比较值相等,p和p2是不一样的值,可是指向的对象相同 if p === p2 { println("p===p2") //p等价于p2,表示两者指向同一个对象 }
Swift中淡化了成员属性的概念,把属性分为两种:ide
var
表示可读可写,let
表示只读)willSet
、didSet
)lazy
修饰)getter
来获取一个值,或者利用setter
来间接设置其余属性。class Account { //定义存储属性,设置默认值,添加属性监听器 var balance:Double = 0.0{ //即将赋值时调用 willSet{ //注意此时修改balance的值没有用 self.balance = 2.0 //newValue表示即将赋值的新值,而且在属性监视器内部调用属性不会引发监视器循环调用 println("Account.balance willSet,newValue=\(newValue),value=\(self.balance)") } //赋值完成后调用 didSet{ //注意此时修改balance的值将做为最终结果 self.balance = 3.0 //oldValue表示已经赋值的旧值,而且在属性监视器内部调用属性不会引发监视器循环调用 println("Account.balance didSet,oldValue=\(oldValue),value=\(self.balance)") } } } class Person { //firstName、lastName、age是存储属性 var firstName:String //var定义表示该存储属性可读可写 var lastName:String let age:Int //let定义表示该存储属性只读 //属性的懒加载,第一次访问才会初始化 lazy var account = Account()//在Swift中懒加载的属性不必定就是对象类型,也能够是基本类型 //fullName是一个计算属性,在get、set方法中不能直接访问计算属性,不然会引发循环调用 var fullName:String{ //获取该计算属性时调用 get{ return firstName + "." + lastName } //设置该计算属性时调用 set{ //set方法中的newValue表示即将赋值的新值,这里是分割字符串 let array = split(newValue, maxSplit: Int.max, allowEmptySlices: false, isSeparator: {$0=="."}) if array.count == 2 { firstName = array[0] lastName = array[1] } } } //构造器方法,注意若是不编写构造方法默认会自动建立一个无参构造方法 init(firstName:String, lastName:String, age:Int){ self.firstName = firstName self.lastName = lastName self.age = age } //定义方法 func showMessage(){ println("name=\(self.fullName),age=\(self.age)") } } //建立对象 var p = Person(firstName: "Liu", lastName: "Ting", age:22) p.showMessage() //结果:name=Liu.Ting,age=22 p.fullName = "Liu.HAHA" //设置计算属性 p.showMessage() //结果:name=Liu.HAHA,age=22 p.account.balance = 10 /* 下面是存储属性监听器方法打印: Account.balance willSet,newValue=10,value=0.0 Account.balance didSet,oldValue=10,value=3.0 */ println("p.account.balance=\(p.account.balance)") //结果:p.account.balance=3.0
getter
来获取一个值,或者利用setter
来间接设置其余属性;lazy
属性必须有初始值,必须是变量不能是常量,由于常量在构造完成以前就已经肯定了值;class Student { //定义类的属性只须要在前面加static关键字便可,也是分为存储属性和计算属性,这里是计算属性 static var skin:Array<String>{ //只定义了getter,表示该计算属性是只读的 get{ return ["yellow", "white", "black"] } } } //读取类的属性 for color in Student.skin { println(color) }
class Person { //定义属性 var name:String var height:Double var age = 0 //1.2.指定构造器方法,注意若是不编写构造方法,默认会自动建立一个无参构造方法 init(name:String, height:Double, age:Int){ self.name = name self.height = height self.age = age } //1.3.便利构造方法,经过调用指定构造方法、提供默认值来简化构造方法实现 convenience init(name:String){ self.init(name:name, height:0.0, age:0) } //2.析构方法,在对象被释放时调用,注意此方法没有括号,没有参数,没法直接调用 deinit{ println("deinit...") } //3.对象方法 func modifyInfoWithAge(age:Int, height:Double){ self.age = age self.height = height } //4.类方法,使用class修饰的方法便是类方法 class func showClassName(){ println("Class name is Person") } } //经过便利构造方法建立对象 var p = Person(name: "liuting") //调用对象方法 p.modifyInfoWithAge(22,height: 170) //调用类方法 Person.showClassName()
下标脚本是一种访问集合的快捷方式,若是咱们自定义的类具备集合类型的功能,咱们能够定义下标脚原本快捷访问该类属性,定义下标脚本是经过关键字subscript
进行的。函数
class Record { //定义属性,store是Record内部的存储结构,这里是字典 var store:[String:String] //指定构造方法 init(data:[String:String]){ self.store = data } //下标脚本,下标索引为整形(注意也能够实现只有getter的只读下标脚本) subscript(index:Int) -> String{ get{ //字典的key进行排序后根据Index整形索引获取字典的值 var key = sorted(Array(self.store.keys))[index] return self.store[key]! } set{ //字典的key进行排序后根据Index整形索引设置字典的值 var key = sorted(Array(self.store.keys))[index] self.store[key] = newValue //newValue和属性同样使用 } } //下标脚本,下标索引为字符串 subscript(key:String) -> String{ get{ return store[key]! } set{ store[key] = newValue } } } //建立对象 var record = Record(data:["name":"liuting","sex":"male"]) println("r[0]=\(record[0])") //结果:r[0]=liuting record["sex"] = "female" println(record["sex"]) //结果:female
和ObjC同样,Swift也是单继承的(能够实现多个协议,此时协议放在后面),子类能够调用父类的属性、方法,重写父类的方法,添加属性监视器,甚至能够将只读属性重写成读写属性。code
//定义一个父类 class Person { var firstName:String var lastName:String var age:Int = 0 var fullName:String{ get{ return firstName + " " + lastName } } //指定构造方法 init(firstName:String,lastName:String){ self.firstName = firstName self.lastName = lastName } //对象方法 func showMessage(){ println("name=\(self.fullName),age=\(self.age)") } //经过final声明,子类没法重写 final func sayHello(){ println("hello world.") } } //定义子类 class Student: Person { //重写属性,为属性添加监视器,重写都须要加override关键字 override var firstName:String{ willSet{ println("firstName willSet") } didSet{ println("firstName didSet") } } //添加子类属性 var score:Double //子类指定构造方法必定要调用父类构造方法 //而且必须在子类存储属性初始化以后调用父类构造方法 init(firstName:String, lastName:String, score:Double){ self.score = score super.init(firstName: firstName, lastName: lastName) } //便利构造方法 convenience init(){ self.init(firstName:"", lastName:"", score:0) } //将只读属性重写成了可写属性 override var fullName:String{ get{ return super.fullName; } set{ let array = split(newValue, maxSplit: Int.max, allowEmptySlices: false, isSeparator: { $0 == "." }) if array.count == 2 { firstName = array[0] lastName = array[1] } } } //重写对象方法 override func showMessage() { println("name=\(self.fullName),age=\(self.age),score=\(self.score)") } } //建立子类对象 var p = Student() p.firstName = "liu" p.showMessage() //结果:name=liu,age=0,score=0 p.fullName = "Liu.Ting" p.showMessage() //结果:name=Liu.Ting,age=0,score=0 p.sayHello()