做爲一門面向對象語言,類也是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()