SwiftTour基礎學習(七)對象和類
使用 class 和類名來創建一個類。類中屬性的聲明和常量、變量聲明一樣,唯一的區別就是它們的上下文是類。同樣,方法和函數聲明也一樣。
class Shape {
var numberOfSides = 0
func simpleDescription() -> String {
return "A shape with \(numberOfSides) sides."
}
}
要創建一個類的實例,在類名後面加上括號。使用點語法來訪問實例的屬性和方法。
var shape = Shape()
shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription()
這個版本的 Shape 類缺少了一些重要的東西:一個構造函數來初始化類實例。使用 init 來創建一個構造器。
class NamedShape {
var numberOfSides: Int = 0
var name: String
init(name: String) {
self.name = name
}
func simpleDescription() -> String {
return "A shape with \(numberOfSides) sides."
}
}
註意 self 被用來區別實例變量。當你創建實例的時候,像傳入函數參數一樣給類傳入構造器的參數。每個屬性都需要賦值--無論是通過聲明(就像 numberOfside)還是通過構造器(就像 name)。
如果你需要在刪除對象之前進行一些清理工作,使用 deinit 創建一個析構函數。
子類的定義方法是在它們的類名後面加上父類的名字,用冒號分割。創建類的時候並不需要一個保準的根類,所以你可以忽略父類。
子類如果要重寫父類的方法的話,需要用 override 標記--如果沒有添加 override 就重寫父類方法的話編譯器會報錯。編譯器同樣會檢測 override 標記的方法是否確實在父類中。
class Square: NamedShape {
var sideLength: Double
init(sideLength: Double, name: String) {
self.sideLength = sideLength
super.init(name: name)
numberOfSides = 4
}
func area() -> Double {
return sideLength * sideLength
}
override func simpleDescription() -> String {
return "A square with sides of length \(sideLength)."
}
}
let test = Square (sideLength: 5.2, name: "my test square")
test.area()
test.simpleDescription()
除了儲存簡單的屬性之外,屬性可以有 getter 和 setter。
class EquilateralTriang: NamedShape {
var sideLength: Double = 0.0
init(sideLength: Double, name: String) {
self.sideLength = sideLength
super.init(name: name)
numberOfSides = 3
}
var perimeter:Double {
get {
return 3.0 * sideLength
}
set {
sideLength = newValue / 3.0
}
}
override func simpleDescription() -> String {
return "An equilateral triagle with sides of length \(sideLength)."
}
}
var triangle = EquilateralTriang (sideLength: 3.1, name: "a triangle")
print(triangle.perimeter)
triangle.perimeter = 9.9
print(triangle.sideLength)
在 perimeter 的 setter 中,新值的名字是 newValue。你可以在 set 之後顯式的設置一個名字。
註意 EquilateralTriangle 類的構造器執行了三步:
1.設置子類聲明的屬性。
2.調用父類的構造器。
3.改變父類定義的屬性值。其他的工作比如調用方法、getters 和 setters 也可以在這個階段完成。
如果你不需要計算屬性,但是仍然需要在設置一個新值之前或者之後運行代碼,使用 willSet 和 didSet。
比如,下面的類確保三角形的邊長總是和正方形的邊長相同。
class TriangleAndSquare {
var triangle: EquilateralTriang {
willSet {
square.sideLength = newValue.sideLength
}
}
var square:Square {
willSet {
triangle.sideLength = newValue.sideLength
}
}
init(size: Double, name: String) {
square = Square (sideLength: size, name: name)
triangle = EquilateralTriang (sideLength: size, name: name)
}
}
var triangleAndSquare = TriangleAndSquare (size: 10, name: "another test shape")
print(triangleAndSquare.square.sideLength)
print(triangleAndSquare.triangle.sideLength)
triangleAndSquare.square = Square (sideLength: 50, name: "larger square")
print(triangleAndSquare.triangle.sideLength)
處理變量的可選值時,你可以在操作(比如方法、屬性和子腳本)之前加 ?。如果 ? 之前的值是 nil,? 後面的東西都會被忽略,並且整個表達式返回 nil。否則,?之後的東西都會被運行。在這兩種情況下,整個表達式的值也是一個可選值。
let optionalSquare: Square? = Square (sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare?.sideLength
END
SwiftTour基礎學習(七)對象和類