Swift中文教程(五)--對象和類


  

 

  Class 類

 

  在Swift中可以用class關鍵字后跟類名創建一個類。在類里,一個屬性的聲明寫法同一個常量或變量的聲明寫法一樣,除非這個屬性是在類的上下文里面,否則,方法和函數的寫法也是這樣:

1 class Shape {
2     var numberOfSides = 0
3     func simpleDescription() -> String {
4         return "A shape with \(numberOfSides) sides."
5     }
6 }

練習:

用let關鍵字添加一個常量屬性,添加另一個方法用來接收參數。

 

  在類名后面加小括號來創建類的實例化,使用.(點號連接符)來訪問實例的方法和屬性:

1 var shape = Shape()
2 shape.numberOfSides = 7
3 var shapeDescription = shape.simpleDescription()

 

  這個版本的Shape類缺少一個重要的東西:構造器--類被創建后的設置。可以使用init來創建一個:

 1 class NamedShape {
 2     var numberOfSides: Int = 0
 3     var name: String
 4     
 5     init(name: String) {
 6         self.name = name
 7     }
 8     
 9     func simpleDescription() -> String {
10         return "A shape with \(numberOfSides) sides."
11     }
12 }

  注意,此處的self是用來區分構造器內的name參數和name屬性的。創建類的實例時,構造器里的參數傳遞和函數的參數傳遞形式是一樣的。每個屬性都需要為其指定一個值,無論是在聲明中(如nameOfSides),或是在構造器內(如name)。

  使用 deinit 來創建一個析構器,來執行對象銷毀時的清理工作。

 

  繼承和多態

 

  子類可以加冒號后直接跟超類名,子類聲明時並不需要非得制定任何標准基類,所以子類后的超類可以被忽略。

  子類的方法覆蓋或重載超類中的實現要加上override標記,否則,編譯器會報錯,編譯器也會檢測被標記為override的重載方法到底有沒有覆蓋到超類。

 

 1 class Square: NamedShape {//接上一例,NamedShape為超類
 2     var sideLength: Double
 3     
 4     init(sideLength: Double, name: String) {
 5         self.sideLength = sideLength
 6         super.init(name: name)
 7         numberOfSides = 4
 8     }
 9     
10     func area() ->  Double {
11         return sideLength * sideLength
12     }
13     
14     override func simpleDescription() -> String {//在此處用override重載了上一例中超類NameSpace的方法simpleDescription
15         return "A square with sides of length \(sideLength)."
16     }
17 }
18 let test = Square(sideLength: 5.2, name: "my test square")
19 test.area()
20 test.simpleDescription()

 

練習:

編寫另一個NamedShape的子類:Circle ,傳入半徑和名字作為參數到其構造器,並在Circle類中實現area和describe方法。

  此外,聲明過的屬性通常還有一個get和一個set方法:

 1 class EquilateralTriangle: NamedShape {
 2     var sideLength: Double = 0.0
 3     
 4     init(sideLength: Double, name: String) {
 5         self.sideLength = sideLength
 6         super.init(name: name)
 7         numberOfSides = 3
 8     }
 9     
10     var perimeter: Double {
11     get {
12         return 3.0 * sideLength
13     }
14     set {
15         sideLength = newValue / 3.0
16     }
17     }
18     
19     override func simpleDescription() -> String {
20         return "An equilateral triagle with sides of length \(sideLength)."
21     }
22 }
23 var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
24 triangle.perimeter
25 triangle.perimeter = 9.9
26 triangle.sideLength

  

  上例中,perimeter的set中值的默認名是newValue,你可以再set后面以小括號的方式為其指定其它的名字。

  請注意, EquilateralTriangle類的構造器有三個不同的步驟:

    第一步,設置子類各個屬性的值;

    第二步,調用超類的構造器;

    第三步,改變超類中定義的屬性的值,其它的方法,get,set等都可以在此一步驟實行。

  如果你不需要計算屬性的值,但是想在設置屬性值之前或之后執行代碼,那么你可以使用willset(之前)和didset(之后)。如下例中的類--確保三角形的邊長始終與矩形邊長相等:

 1 class TriangleAndSquare {
 2     var triangle: EquilateralTriangle {
 3     willSet {
 4         square.sideLength = newValue.sideLength
 5     }
 6     }
 7     var square: Square {
 8     willSet {
 9         triangle.sideLength = newValue.sideLength
10     }
11     }
12     init(size: Double, name: String) {
13         square = Square(sideLength: size, name: name)
14         triangle = EquilateralTriangle(sideLength: size, name: name)
15     }
16 }
17 var triangleAndSquare = TriangleAndSquare(size: 10, name: "another test shape")
18 triangleAndSquare.square.sideLength
19 triangleAndSquare.triangle.sideLength
20 triangleAndSquare.square = Square(sideLength: 50, name: "larger square")
21 triangleAndSquare.triangle.sideLength

 

  類的方法與函數有一個重要的區別:函數的參數名僅作用於此函數內,而方法的參數名可以用於調用方法(第一個參數除外)。缺省時,一個方法有一個同名的參數,調用時就是方法本身。你可以指定第二個名字,在方法內部使用:

1 class Counter {
2     var count: Int = 0
3     func incrementBy(amount: Int, numberOfTimes times: Int) {
4         count += amount * times
5     }
6 }
7 var counter = Counter()
8 counter.incrementBy(2, numberOfTimes: 7)

 

  當與可選值(詳見第三章的If語句介紹)一起工作時,你可以在方法或屬性前寫 "?" 操作符。如果值在"?"之前就已經是 nil ,所有在 "?" 之后的都會自動忽略,而整個表達式是 nil 。另外,可選值是未封裝的,所有 "?" 之后的都作為未封裝的值。在這兩種情況中,整個表達式的值是可選值:

1 let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")//?可選值的介紹詳見第三章的If語句部分
2 let sideLength = optionalSquare?.sideLength

 

 

 

 謝謝,Swifter-QQ群:362232993,同好者進~ 

github地址:https://github.com/Joejo/Swift-lesson-for-chinese

 

 

  

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM