在一個類中能夠嵌套一個或者多個類。它們的嵌套形式也是不一樣的,大體分爲了兩種:直接嵌套和屢次嵌套。下面依次講解這兩種方式。ide
當一個類或者多個類直接嵌套在另一個類,這時就構成直接嵌套,如圖8.6所示。post
圖8.6 類的嵌套spa
在圖8.6中,類2、類3和類4都是直接嵌套在類1中。對於這種狀況,使用類1的實例屬性和方法,語法形式以下:orm
類1().屬性對象
類1().方法教程
使用類1的類型屬性和方法的形式以下:ip
類1.屬性開發
類1.方法字符串
使用類2的實例屬性和方法,語法形式以下:it
類1.類2().屬性
類1.類2().方法
使用類2的類型屬性和方法的形式以下:
類1.類2.屬性
類1.類2.方法
類3和類4的使用方法相似。
【示例8-21】如下將定義一個直接嵌套的類NewClass,在此類中嵌套了Str1Class、Str2Class、Str3Class這3個類,和一個能夠輸出這3個類中屬性內容的方法。在Str1Class、Str2Class、Str3Class這三個類中又定義了類型屬性,它們都會返回一個字符串。代碼以下:
import Foundation
class NewClass {
class func printstr(str:String){
print(str)
}
//Str1Class類
class Str1Class{
class var str:String{
return "Swift"
}
}
//Str2Class類
class Str2Class{
class var str:String{
return "Hello"
}
}
//Str3Class類
class Str3Class{
class var str:String{
return "World"
}
}
}
//調用
NewClass.printstr(NewClass.Str1Class.str)
NewClass.printstr(NewClass.Str2Class.str)
NewClass.printstr(NewClass.Str3Class.str)
在此代碼中,在一個NewCllass類中有包含了3個類,分別爲Str1Class、Str2Class、Str3Class。運行結果以下所示:
Swift
Hello
World
Swift中,類的嵌套不只容許一次嵌套,還容許屢次嵌套。這時的嵌套形式如圖8.7所示。
圖8.7 類的嵌套2
類3和類4是直接嵌套在類2中,而類2又直接嵌套在類1。這樣造成了多層嵌套。這時,若是訪問類1的實例屬性和方法,其語法形式以下:
類1().屬性
類1().方法
訪問類1的類型屬性和方法,其語法形式以下:
類1.屬性
類1.方法
若是要訪問類2的實例屬性和方法,對應的語法形式以下:
類1.類2().屬性
類1.類2().方法
訪問類2的類型屬性和方法,對應的語法形式以下:
類1.類2.屬性
類1.類2.方法
若是要訪問類3的實例屬性和方法,對應的語法形式以下:
類1.類2.類3().屬性
類1.類2.類3().方法
若是要訪問類3的類型屬性和方法,對應的語法形式以下:
類1.類2.類3.屬性
類1.類2.類3.方法
【示例8-22】如下將定義一個屢次嵌套的類NewClass,在此類中嵌套了StrClass類,和一個能夠輸出屬性內容的方法。在StrClass類中又嵌套了Str1Class、Str2Class、Str3Class這3個類,它們都會返回一個字符串。代碼以下:
import Foundation
class NewClass {
class func printstr(str:String){
print(str)
}
// StrClass類
class StrClass{
// StrClass1類
class Str1Class{
class var str:String{
return "Hello"
}
}
// StrClass2類
class Str2Class{
class var str:String{
return "Swift"
}
}
// StrClass3類
class Str3Class{
class var str:String{
return "World"
}
}
}
}
//調用
NewClass.printstr(NewClass.StrClass.Str1Class.str)
NewClass.printstr(NewClass.StrClass.Str2Class.str)
NewClass.printstr(NewClass.StrClass.Str3Class.str)
在此代碼中,在一個NewCllass類中有包含了1個類StrClass,在StrClass類中又包含了3個類,分別爲Str1Class、Str2Class、Str3Class。運行結果以下所示:
Hello
Swift
World
在類或者其餘的類型中,聲明的屬性和變量/常量,都不能夠爲空。爲了解決這一問題,Swift提出了可選類型。經過可選類型定義的元素能夠爲空或者是不爲空,可是如何要使用這些可選類型的值又成爲一大難題。Swift接着就提出了可選連接。可選連接能夠判斷請求或調用的目標(屬性、方法、下標腳本等)是否爲空。若是目標有值,那麼調用就會成功;相反,則返回空(nil)。對於屢次請求或調用的能夠被連接在一塊兒造成一個鏈條。Swift中的可選連接和Objective-C中的消息爲空相似,可是Swift可使用在任意的類型中使用,而且失敗與否能夠被檢測到。如下將詳細講解可選連接的內容。
可選連接其實就是使用「?」問號操做符對可選類型實現的一種運算。開發者能夠在想要調用的屬性、下標腳本和方法的可選值後面添加一個「?」問號來進行可選連接的定義。如下就是對於這些可選連接的定義形式:
屬性名? //屬性的可選連接
下標腳本? //下標腳本的可選連接
方法名? //方法的可選連接
對象可選連接的調用形式以下:
對象名.可選連接
【示例8-23】如下將判斷值是否存在,其代碼以下:
import Foundation
class Residence {
//定義一個可選類型的類型屬性numberOfRooms
class var numberOfRooms:Int?{
return 100
}
var number:Int?
}
let newClass=Residence()
if let a=Residence.numberOfRooms { //判斷a是否有值
print("目標有值")
}else{
print("目標爲空")
}
if let a=newClass.number { //可選連接
print("目標有值")
}else{
print("目標爲空")
}
在此代碼中,因爲umberOfRooms的屬性值不爲空,因此會出現"目標有值",可是對於number屬性來講,沒有賦初值即number屬性爲nil,因此會出現"目標爲空"運行結果以下所示:
目標有值
目標爲空
注意:在定屬性、下標腳本以及方法定義爲可選連接時,這些屬性、下標腳本和方法都必須是可選類型,不然程序就會出現如下的錯誤。如如下的代碼,是對屬性進行的可選連接:
import Foundation
class NewClass{
var value:Int=10
}
let newClass=NewClass()
let newValue=newClass.value?
print(newValue)
因爲在此代碼中對一個不是可選類型的屬性進行了可選連接定義,致使程序出現瞭如下的錯誤:
Operand of postfix '?' should have optional type; type is 'Int'
開發者可使用可選連接的可選值來調用屬性、下標腳本和方法,並檢查這些內容調用是否成功。如下就是經過可選連接調用屬性、下標腳本、方法的詳細講解。
1.經過可選連接調用屬性
經過可選連接調用屬性的語法形式以下:
可選連接.屬性名
【示例8-24】如下將經過自判斷可選連接來調用屬性值,並獲取這個屬性值。代碼以下:
import Foundation
class Person {
var residence: Residence?
}
class Residence {
var numberOfRooms = 10
}
let john = Person()
if let roomCount = john.residence?.numberOfRooms { //經過可選連接調用屬性
print("John在房子中有 \(roomCount)個房間")
} else {
print("沒法檢索房間數")
}
因爲john.residence是空,因此這個可選連接就會失敗,可是不會出現錯誤,會返回一個nil。運行結果以下:
沒法檢索房間數
若是不想返回nil l,開發者須要將john.residence設置爲不爲空。如如下的代碼,將john.residence設置爲johnResidence。代碼以下:
let john = Person()
let johnResidence = Residence()
john.residence=johnResidence
if let roomCount = john.residence?.numberOfRooms { //經過可選連接調用屬性
print("John在房子中有 \(roomCount)個房間")
} else {
print("沒法檢索房間數")
}
運行結果以下:
John在房子中有 10個房間
2. 經過可選連接調用下標腳本
經過可選連接調用下標腳本的語法形式以下:
可選連接.[下標]
【示例8-25】如下將經過自判斷可選連接來調用下標腳本。代碼以下:
import Foundation
class Person {
var residence: Residence?
}
class Residence {
subscript(i: Int) -> Int {
return i
}
}
let john = Person()
if let firstRoomName = john.residence?[5] { //經過可選連接調用下標腳本
print("John在房子中有 \(firstRoomName)個房子")
} else {
print("沒法檢索房間數")
}
運行結果以下所示:
沒法檢索房間數
注意:當開發者使用可選鏈來調用子腳本的時候,你應該將「?」問號放在下標腳本括號的前面而不是後面。可選鏈的問號通常直接跟在自判斷表達語句的後面。不然程序就會出現錯誤。如如下的代碼就將上面的代碼作了一下修改,代碼以下:
let john = Person()
if let firstRoomName = john.residence[5]? { //經過可選連接調用下標腳本
print("John在房子中有 \(firstRoomName)個房子")
} else {
print("沒法檢索房間數")
}
在此代碼中就「?」問號放在了下標腳本括號得後面,致使程序出現瞭如下的錯誤:
'Residence?' does not have a member named 'subscript'
3.經過可選連接調用方法
經過可選連接調用方法的語法形式以下:
可選連接.方法
【示例8-26】如下將經過自判斷可選連接來調用方法printNumberOfRooms(),此方法的功能是輸出numberOfRooms的值。代碼以下:
import Foundation
class Person {
var residence: Residence?
}
class Residence {
var numberOfRooms=10
func printNumberOfRooms() {
print("The number of rooms is \(numberOfRooms)")
}
}
let john = Person()
if let a: ()=john.residence?.printNumberOfRooms() { ////經過可選連接調用方法
print("打印房間數")
} else {
print("沒法打印房間數")
}
運行結果以下:
沒法打印房間數
開發者能夠將多個可選連接放在一塊兒,如如下的代碼,此代碼實現的功能是將獲取屬性street的內容。代碼以下:
import Foundation
// Person類,定義了屬性residence
class Person {
var residence: Residence?
}
// Residence類,定義了屬性address
class Residence {
var address: Address?
}
// Address類定義了屬性street
class Address {
var street: String?
}
//實例化對象
let john = Person()
let johnsHouse = Residence()
john.residence = johnsHouse
let johnsAddress = Address()
//賦值
johnsHouse.address=johnsAddress
johnsAddress.street = "Laurel Street"
if let johnsStreet = john.residence?.address?.street { //連接了兩個可選連接
print("John的地址爲: \(johnsStreet)")
} else {
print("沒法檢索地址")
}
在此代碼中,john.residence如今存在一個實例johnsHouse,而不是nil,而john.residence?.address如今也存在一個實例johnsAddress,併爲street設置了實例的值。因此在執行程序後,會返回Street的值。運行結果以下:
John的地址爲: Laurel Street
本文選自:Swift2.0語言快速入門v3.0 大學霸內部資料,轉載請註明出處,尊重技術尊重IT人!