Swift3.0P1 語法指南——繼承

原檔:https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Inheritance.html#//apple_ref/doc/uid/TP40014097-CH17-ID193html

參考:http://wiki.jikexueyuan.com/project/swift/chapter2/13_Inheritance.htmlios

一、繼承

在Swift中,繼承是類和其餘類型區分開的基本行爲。swift

在 Swift 中,類能夠調用和訪問超類的方法,屬性和下標(subscripts),而且能夠重寫這些方法、屬性和下標腳原本優化或修改它們的行爲。Swift 會檢查你的重寫定義在超類中是否有匹配的定義,以此確保你的重寫行爲是正確的。markdown

能夠爲類中繼承來的屬性添加屬性觀察器,這樣一來,當屬性值改變時,類就會被通知到。能夠爲任何屬性添加屬性觀察器,不管它本來被定義爲存儲型屬性仍是計算型屬性。app

二、定義基類(Base Class)

沒有繼承任何類的類,稱爲基類。ide

注意:Swift中任何類都沒有繼承一個通用的類(如Objective-C中的NSObject),因此定義類時只要沒有指定超類,該類就自動稱爲基類。優化

下面是一個基類Vehicle:ui

1 class Vehicle {
2     var currentSpeed = 0.0
3     var description: String {
4         return "traveling at \(currentSpeed) miles per hour"
5     }
6     func makeNoise() {
7         // do nothing - an arbitrary vehicle doesn't necessarily make a noise
8     }
9 }

能夠建立它的一個實例:spa

1 let someVehicle = Vehicle()

訪問它的description屬性:code

1 print("Vehicle: \(someVehicle.description)")
2 // Vehicle: traveling at 0.0 miles per hour

三、子類化(Subclassing)

子類化,也就是在一個已存在的類的基礎上新建一個類。子類繼承父類(superclass)的特性,而後你能夠從新定義,也能夠定義新的特性。

1 class SomeSubclass: SomeSuperclass {
2     // subclass definition goes here
3 }

下面,新建Vehicle的子類:

1 class Bicycle: Vehicle {
2     var hasBasket = false
3 }

Bicycle自動得到Vehicle的全部特性,包括currentSpeed和description屬性、makeMoise()方法。

此外,Bicycle添加了一個新的默認值爲false的屬性hasBasket。

建立一個Bicycle的實例:

1 let bicycle = Bicycle()
2 bicycle.hasBasket = true

能夠修改它從父類繼承下來的屬性:

1 bicycle.currentSpeed = 15.0
2 print("Bicycle: \(bicycle.description)")
3 // Bicycle: traveling at 15.0 miles per hour

子類還能夠被子類化:

1 class Tandem: Bicycle {
2     var currentNumberOfPassengers = 0
3 }

建立一個Tandem的實例:

1 let tandem = Tandem()
2 tandem.hasBasket = true
3 tandem.currentNumberOfPassengers = 2
4 tandem.currentSpeed = 22.0
5 print("Tandem: \(tandem.description)")
6 // Tandem: traveling at 22.0 miles per hour

四、重寫(Overriding)

子類能夠提供實例方法、類型方法、實例屬性、類型屬性、下標的自定義實現,不然,將從超類繼承。這就是重寫的概念。

若是要重寫某個特性,你須要在重寫定義的前面加上override關鍵字。

這麼作,你就代表了你是想提供一個重寫版本,而非錯誤地提供了一個相同的定義。意外的重寫行爲可能會致使不可預知的錯誤,任何缺乏override關鍵字的重寫都會在編譯時被診斷爲錯誤。

override關鍵字會提醒 Swift 編譯器去檢查該類的超類(或其中一個父類)是否有匹配重寫版本的聲明。這個檢查能夠確保你的重寫定義是正確的。

五、訪問超類的方法、屬性和下標

當你在子類中重寫父類的方法,屬性或下標腳本時,有時在你的重寫版本中使用已經存在的父類實現會大有裨益。好比,你能夠優化已有實現的行爲,或在一個繼承來的變量中存儲一個修改過的值。

在合適的地方,你能夠經過使用super前綴來訪問父類版本的方法,屬性或下標腳本:

  • 在方法someMethod的重寫實現中,能夠經過super.someMethod()來調用超類版本的someMethod方法。
  • 在屬性someProperty的 getter 或 setter 的重寫實現中,能夠經過super.someProperty來訪問超類版本的someProperty屬性。
  • 在subscript的重寫實現中,能夠經過super[someIndex]來訪問超類版本中的相同下標腳本。

六、重寫方法

在子類中,你能夠重寫繼承來的實例方法或類方法,提供一個定製或替代的方法實現。

1 class Train: Vehicle {
2     override func makeNoise() {
3         print("Choo Choo")
4     }
5 }

調用重寫的方法:

1 let train = Train()
2 train.makeNoise()
3 // prints "Choo Choo"

七、重寫屬性

你能夠重寫繼承來的實例屬性或類屬性,提供本身定製的getter和setter,或者添加屬性觀察器來觀察屬性值何時發生改變。

(1)重寫屬性的getter和setter

你能夠提供定製的 getter(或 setter)來重寫任意繼承來的屬性,不管繼承來的屬性是存儲型的仍是計算型的屬性。子類並不知道繼承來的屬性是存儲型的仍是計算型的,它只知道繼承來的屬性會有一個名字和類型。你在重寫一個屬性時,必需將它的名字和類型都寫出來。這樣才能使編譯器去檢查你重寫的屬性是與超類中同名同類型的屬性相匹配的。

你能夠將一個繼承來的只讀屬性重寫爲一個讀寫屬性,只須要你在重寫版本的屬性裏提供 getter setter 便可。可是,你不能夠將一個繼承來的讀寫屬性重寫爲一個只讀屬性。

注意:若是你在重寫屬性中提供了 setter,那麼你也必定要提供 getter。若是你不想在重寫版本中的 getter 裏修改繼承來的屬性值,你能夠直接經過super.someProperty來返回繼承來的值,其中someProperty是你要重寫的屬性的名字。

class Car: Vehicle {
    var gear = 1
    override var description: String {
        return super.description + " in gear \(gear)"
    }
}

description屬性的override從調用super.description開始,在父類的基礎上增長了一些描述。

1 let car = Car()
2 car.currentSpeed = 25.0
3 car.gear = 3
4 print("Car: \(car.description)")
5 // Car: traveling at 25.0 miles per hour in gear 3

(2)重寫屬性觀察器(Overriding Property Observers)

注意:不能給繼承的常量存儲屬性和只讀計算型屬性添加屬性觀察器,這些屬性的值不能設置,因此也沒法添加相應的willSet和didSet方法。另外,對於同一個屬性,不能同時重寫setter和重寫屬性觀察器,若是已經爲一個屬性提供了自定義的setter,那麼只能在這個setter中觀察屬性的變化。

1 class AutomaticCar: Car {
2     override var currentSpeed: Double {
3         didSet {
4             gear = Int(currentSpeed / 10.0) + 15        }
5     }
6 }

只要設置currentSpeed屬性,didSet就會設置相應的gear。

1 let automatic = AutomaticCar()
2 automatic.currentSpeed = 35.0
3 print("AutomaticCar: \(automatic.description)")
4 // AutomaticCar: traveling at 35.0 miles per hour in gear 4
5

八、防止重寫

你能夠經過把方法,屬性或下標腳本標記爲final來防止它們被重寫,只須要在聲明關鍵字前加上final特性便可。(例如:final varfinal funcfinal class func, 以及 final subscript

若是你重寫了final方法,屬性或下標,在編譯時會報錯。在類擴展中的方法,屬性或下標腳本也能夠在擴展的定義裏標記爲 final。

你能夠經過在關鍵字class前添加final特性(final class)來將整個類標記爲 final 的,這樣的類是不可被繼承的,任何子類試圖繼承此類時,在編譯時會報錯。

相關文章
相關標籤/搜索