標籤:
在class 後面跟類名來建立一個類。除了上下文是類以外,聲明一個屬性和常量,變數聲明是一樣的,方法和函數也是如此。
class Shape { var numberOfSides = 0 func simpleDescription() -> String { return "A shape with \(numberOfSides) sides." }}
試一試:
添加一個常量屬性,再添加一個含一個參數的函數。
通過在類名的後面加小括弧來建立這個類的執行個體。用點文法來訪問這個執行個體的屬性和方法。
var shape = Shape()shape.numberOfSides = 7var 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來區分name是屬性還是參數。建立一個類的執行個體時這裡的參數傳遞就像函數調用時的參數傳遞一樣。每一個屬性都需要賦值,在聲明的時候(如numberOfSides)或是在初始化器中(如name)。
當你需要在對象釋放前做一些清理工作,可以用deinit 來建立一個析構器。
子類類名後面是父類名,中間用冒號: 隔開。沒有強求子類要有標準的根類,所以可以根據需要省略父類。
子類的方法要覆蓋父類方法的實現時,要用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()
試一試:
寫一個繼承自NameShape的子類Circle,初始化器中接收radius和name參數。並實現area和describe方法。
除了簡單的儲存屬性,屬性還有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")triangle.perimetertriangle.perimeter = 9.9triangle.sideLength
在perimeter的setter方法中,新值有一個隱式的名newValue.你可以在set方法的後面加一個括弧顯式的提供一個新值名字。
對於EquilateralTriangle中的初始化器做了三件事:
1.設定子類聲明的屬性的值
2.調用父類的初始化器
3.改變被父類定義的屬性值。當然通過其他的如方法,getter,setter,都可以完成這一點。
如果你不需要計算屬性但是又需要在設定一個新值之後,在運行之前提供一些代碼,可以用willset和didset。比如,下面的類確保了三角形和正方形的邊長都相同。
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")triangleAndSquare.square.sideLengthtriangleAndSquare.triangle.sideLengthtriangleAndSquare.square = Square(sideLength: 50, name: "larger square")triangleAndSquare.triangle.sideLength
類中的方法和函數有一個重要的不同點,函數的參數名只能在函數中使用,但是方法中的參數名在你調用方法時還需要用上(第一個參數的參數名除外)。預設情況下,方法的參數名在調用或在方法內部使用時是相同的,你可以標識第二個名字,在方法中使用。
class Counter { var count: Int = 0 func incrementBy(amount: Int, numberOfTimes times: Int) { count += amount * times }}var counter = Counter()counter.incrementBy(2, numberOfTimes: 7)
當用到optional值時,你可以在操作之前加一個問號?。如果在?之前的值是nil,那麼問號?之後的代碼就被忽略,都被視為是nil。否則,這個optional值被解包,問號?之後的就作為解包值。下面兩種情況下,整個運算式的值都是一個optional值。
let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")let sideLength = optionalSquare?.sideLength
Swift學習—對象和類