對象和類

使用class和類名來建立一個類。類中屬性的聲明和常量、變量聲明同樣,惟一的區別就是它們的上下文是類。一樣,方法和函數聲明也同樣。javascript

class Shape { var numberOfSides = 0 func simpleDescription() -> String { return "A shape with \(numberOfSides) sides." } }

練習: 使用let添加一個常量屬性,再添加一個接收一個參數的方法。php

要建立一個類的實例,在類名後面加上括號。使用點語法來訪問實例的屬性和方法。java

var shape = Shape() shape.numberOfSides = 7 var shapeDescription = shape.simpleDescription()

這個版本的Shape類缺乏了一些重要的東西:一個構造函數來初始化類實例。使用init來建立一個構造器。swift

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被用來區別實例變量。當你建立實例的時候,像傳入函數參數同樣給類傳入構造器的參數。每一個屬性都須要賦值——不管是經過聲明(就像numberOfSides)仍是經過構造器(就像name)。ide

若是你須要在刪除對象以前進行一些清理工做,使用deinit建立一個析構函數。函數

子類的定義方法是在它們的類名後面加上父類的名字,用冒號分割。建立類的時候並不須要一個標準的根類,因此你能夠忽略父類。ui

子類若是要重寫父類的方法的話,須要用override標記——若是沒有添加override就重寫父類方法的話編譯器會報錯。編譯器一樣會檢測override標記的方法是否確實在父類中。spa

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()

練習: 建立NamedShape的另外一個子類Circle,構造器接收兩個參數,一個是半徑一個是名稱,在子類Circle中實現area()simpleDescription()方法。code

除了儲存簡單的屬性以外,屬性能夠有 getter 和 setter 。對象

class EquilateralTriangle: 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 = EquilateralTriangle(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也能夠在這個階段完成。

若是你不須要計算屬性,可是仍然須要在設置一個新值以前或者以後運行代碼,使用willSetdidSet

好比,下面的類確保三角形的邊長老是和正方形的邊長相同。

class TriangleAndSquare { var triangle: EquilateralTriangle { 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 = EquilateralTriangle(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
相關文章
相關標籤/搜索