swift 繼承和構造器

來源:互聯網
上載者:User

標籤:des   color   使用   strong   width   io   

繼承
class Vehicle {    var numberOfWheels: Int    var maxPassengers: Int    func description() -> String {        return "\(numberOfWheels) wheels; up to \(maxPassengers) passengers"    }    init() {        numberOfWheels = 0        maxPassengers = 1    }}class Bicycle: Vehicle {    init() {        super.init()        numberOfWheels = 2    }}
重寫

如果要重寫某個特性,你需要在重寫定義的前面加上override關鍵字。這麼做,你就表明了你是想提供一個重寫版本,而非錯誤地提供了一個相同的定義。 你可以通過把方法,屬性或下標指令碼標記為final來防止它們被重寫,只需要在聲明關鍵字前加上@final特性即可。(例如:@final var, @final func, @final class func, 以及 @final subscript) 你可以通過在關鍵字class前添加@final特性(@final class)來將整個類標記為 final 的,這樣的類是不可被繼承的,否則會報編譯錯誤。

  class Car: Vehicle {    var speed: Double = 0.0    init() {        super.init()        maxPassengers = 5        numberOfWheels = 4    }    override func description() -> String {        return super.description() + "; "            + "traveling at \(speed) mph"    }    override var speed: Double  {    get {        return super.speed    }    set {        super.speed = min(newValue, 40.0)    }    }     override var speed: Double {    didSet {        gear = Int(speed / 10.0) + 1    }    }}
儲存型屬性的初始賦值

類和結構體在執行個體建立時,必須為所有儲存型屬性設定合適的初始值。儲存型屬性的值不能處於一個未知的狀態。 當你為儲存型屬性設定預設值或者在構造器中為其賦值時,它們的值是被直接設定的,不會觸發任何屬性觀測器(property observers)。

預設屬性值 初始化屬性

預設值將屬性的初始化和屬性的聲明結合的更緊密。使用預設值能讓你的構造器更簡潔、更清晰,且能通過預設值自動推匯出屬性的類型;

  struct Fahrenheit {    var temperature = 32.0}
構造器 初始化屬性

構造器在建立某特定類型的新執行個體時調用。以關鍵字init命名。

struct Fahrenheit {    var temperature: Double    init() {        temperature = 32.0    }}

構造器並不像函數和方法那樣在括弧前有一個可辨別的名字。所以在調用構造器時,主要通過構造器中的參數名和類型來確定需要調用的構造器。
正因為參數如此重要,如果你在定義構造器時沒有提供參數的外部名字,Swift 會為每個構造器的參數自動產生一個跟內部名字相同的外部名,就相當於在每個構造參數之前加了一個雜湊符號。

  struct Celsius {    var temperatureInCelsius: Double = 0.0    init(fromFahrenheit fahrenheit: Double) {        temperatureInCelsius = (fahrenheit - 32.0) / 1.8    }    init(fromKelvin kelvin: Double) {        temperatureInCelsius = kelvin - 273.15    }}

只要在構造過程結束前常量的值能確定,你可以在構造過程中的任意時間點修改常量屬性的值。
對某個類執行個體來說,它的常量屬性只能在定義它的類的構造過程中修改;不能在子類中修改。

class SurveyQuestion {    let text: String = "sss";    var response: String?    init(_ text: String) {        self.text = text    }    func ask() {        println(text)    }}var a  = SurveyQuestion("dddd")a.ask();
預設構造器

Swift 將為所有屬性已提供預設值的且自身沒有定義任何構造器的結構體或基類,提供一個預設的構造器

  class ShoppingListItem {    var name: String?    var quantity = 1    var purchased = false}var item = ShoppingListItem()
逐一成員構造器---只針對結構體..類沒有該構造器

如果結構體對所有儲存型屬性提供了預設值且自身沒有提供定製的構造器,它們能自動獲得一個逐一成員構造器。

struct Size {    var width = 0.0, height = 0.0}let twoByTwo = Size(width: 2.0, height: 2.0)

如果你為某個實值型別定義了一個定製的構造器,你將無法訪問到預設構造器(如果是結構體,則無法訪問逐一物件建構器)。這個限制可以防止你在為實值型別定義了一個更複雜的,完成了重要準備構造器之後,別人還是錯誤的使用了那個自動產生的構造器。

構造器代理

構造器可以通過調用其它構造器來完成執行個體的部分構造過程。這一過程稱為構造器代理,它能減少多個構造器間的代碼重複。 就是嵌套構造器方法
對於實值型別,你可以使用self.init在自訂的構造器中引用其它的屬於相同實值型別的構造器。並且你只能在構造器內部調用self.init。

struct Rect {    var origin = Point()    var size = Size()    init() {}    init(origin: Point, size: Size) {        self.origin = origin        self.size = size    }    init(center: Point, size: Size) {        let originX = center.x - (size.width / 2)        let originY = center.y - (size.height / 2)        self.init(origin: Point(x: originX, y: originY), size: size)    }}
指定構造器和便利構造器
  • 指定構造器必須調用其直接父類的的指定構造器。
  • 便利構造器必須調用同一類中定義的其它構造器。
  • 便利構造器必須最終以調用一個指定構造器結束。

便利構造器需要在init關鍵字之前放置convenience關鍵字,並使用空格將它們倆分開:

  class Food {    var name: String    init(name: String) {        self.name = name    }    convenience init() {        self.init(name: "[Unnamed]")    }}

與方法、屬性和下標不同,在重載構造器時你沒有必要使用關鍵字override。

如果你重載的構造器是一個指定構造器,你可以在子類裡重載它的實現,並在自訂版本的構造器中調用父類版本的構造器。
如果你重載的構造器是一個便利構造器,你的重載過程必須通過調用同一類中提供的其它指定構造器來實現。

自動構造器的繼承
  • 如果子類沒有定義任何指定構造器,它將自動繼承所有父類的指定構造器。
  • 如果子類提供了所有父類指定構造器的實現--不管是通過規則1繼承過來的,還是通過自訂實現的--它將自動繼承所有父類的便利構造器。
通過閉包和函數來設定屬性的預設值

這種類型的閉包或函數一般會建立一個跟屬性類型相同的臨時變數,然後修改它的值以滿足預期的初始狀態,最後將這個臨時變數的值作為屬性的預設值進行返回。注意閉包結尾的大括弧後面接了一對空的小括弧。這是用來告訴 Swift 需要立刻執行此閉包。如果你忽略了這對括弧,相當於是將閉包本身作為值賦值給了屬性,而不是將閉包的傳回值賦值給屬性。如果你使用閉包來初始化屬性的值,請記住在閉包執行時,執行個體的其它部分都還沒有初始化。這意味著你不能夠在閉包裡訪問其它的屬性,就算這個屬性有預設值也不允許。同樣,你也不能使用隱式的self屬性,或者調用其它的執行個體方法。每當一個新的執行個體建立時,對應的賦值閉包會執行,

struct Checkerboard {    let boardColors: Bool[] = {        var temporaryBoard = Bool[]()        var isBlack = false        for i in 1...10 {            for j in 1...10 {                temporaryBoard.append(isBlack)                isBlack = !isBlack            }            isBlack = !isBlack        }        return temporaryBoard        }()    func squareIsBlackAtRow(row: Int, column: Int) -> Bool {        return boardColors[(row * 10) + column]    }}
相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.