繼承
類可以從另一個類繼承方法、屬性和其他特性,繼承類稱為子類,被繼承類為其超類。Swift的類可以調用和訪問超類的方法、屬性和下標,并能重寫這些版本以改進或修改其行為。
類還可以將屬性觀察器添加到繼承的屬性,屬性觀察器可以添加到任何屬性。
<br />
定義基類
基類是不繼承任何一個類的類。
注意
Swift類不會從通用基類繼承,未指定超類的自定義類自動成為基類。
以下為一個自定義Vehicle基類:
class Vehicle {
var currentSpeed = 0.0
var description: String {
return "traveling at \(currentSpeed) miles per hour"
}
func makeNoise() {
// do nothing - an arbitrary vehicle doesn't necessarily make a noise
}
}
使用初始化器語法創建一個類實例:
let someVehicle = Vehicle()
訪問其description屬性:
print("Vehicle: \(someVehicle.description)")
// Vehicle: traveling at 0.0 miles per hour
<br />
子類化
子類化是將一個新類置于現有類之上的行為,子類繼承現有類的特性,也可以向子類添加新特性。
繼承語法如下:
class SomeSubclass: SomeSuperclass {
// subclass definition goes here
}
子類化Vehicle類:
class Bicycle: Vehicle {
var hasBasket = false
}
let bicycle = Bicycle()
bicycle.hasBasket = true
bicycle.currentSpeed = 15.0
print("Bicycle: \(bicycle.description)")
// Bicycle: traveling at 15.0 miles per hour
子類繼續子類化:
class Tandem: Bicycle {
var currentNumberOfPassengers = 0
}
let tandem = Tandem()
tandem.hasBasket = true
tandem.currentNumberOfPassengers = 2
tandem.currentSpeed = 22.0
print("Tandem: \(tandem.description)")
// Tandem: traveling at 22.0 miles per hour
<br />
重寫
子類可以提供自定義的從超類繼承來的實例方法、類型方法、實例屬性、類型屬性或下標,稱為重寫。
使用override關鍵字重寫超類的特性,沒有關鍵字的任何重寫會導致編譯錯誤。
訪問超類方法、屬性和下標
當子類重寫方法、屬性或下標時,可以將現有超類的實現用作重寫的一部分,即在超類實現基礎上重寫。這時使用super前綴訪問方法、屬性或下標的超類版本:
名為someMethod()的重寫方法可以通過在重寫方法實現中調用super.someMetho()來調用someMethod()的超類版本。
被稱為someProperty的被覆蓋的屬性可以在超級的getter或setter實現中以super.someProperty方式訪問someProperty的超類版本。
someIndex的覆蓋下標可以從覆蓋的下標實現中訪問與super [someIndex]相同的下標的超類版本。
方法重寫
可以重寫繼承的實例或類型方法來提供子類中定制或替代方法的方法。
class Train: Vehicle {
override func makeNoise() {
print("Choo Choo")
}
}
let train = Train()
train.makeNoise()
// Prints "Choo Choo"
屬性重寫
可以重寫繼承的實例或類型屬性,為該屬性提供自定義getter和setter,或添加屬性觀察器以啟用重寫屬性來觀察底層屬性值何時更改。
getter和setter屬性重寫
可以提供自定義的getter(和setter)來覆蓋任何繼承的屬性,必須始終聲明要覆蓋的屬性名和類型,以便編譯器檢查重寫是否與具有同名同類型的超類屬性匹配。
可以為超類的只讀屬性的重寫同時提供getter和setter修改為讀寫屬性,但不能將超類的讀寫屬性重寫為只讀屬性。
注意
當重寫屬性提供了setter時,還必須提供getter。若不想覆蓋getter修改繼承屬性的值,可以從getter中返回super.someProperty以維持超類屬性的getter實現。
以下為子類重寫超類description屬性并在超類實現基礎上添加新功能:
class Car: Vehicle {
var gear = 1
override var description: String {
return super.description + " in gear \(gear)"
}
}
let car = Car()
car.currentSpeed = 25.0
car.gear = 3
print("Car: \(car.description)")
// Car: traveling at 25.0 miles per hour in gear 3
屬性觀察器重寫
重寫屬性會講超類的屬性觀察器添加到繼承的屬性,不論該屬性的實現方法如何都將能夠在繼承屬性的值更改時收到通知。
注意
不能將屬性觀察器添加到繼承的常量存儲型屬性或只讀計算型屬性,因為這些屬性值不能更改。不能為同一屬性同時提供重寫的setter和重寫的屬性觀察器,若要監聽屬性值的更改,并且已經提供重寫的setter,則可以簡單地監聽重寫的setter中任何值的更改。
class AutomaticCar: Car {
override var currentSpeed: Double {
didSet {
gear = Int(currentSpeed / 10.0) + 1
}
}
}
let automatic = AutomaticCar()
automatic.currentSpeed = 35.0
print("AutomaticCar: \(automatic.description)")
// AutomaticCar: traveling at 35.0 miles per hour in gear 4
<br />
防止重寫
通過將方法、屬性或下標標記為final防止被子類重寫,如final var,final func,final class fun和final subscript。
任何試圖在子類中重寫標記為final的方法、屬性或下標都將報告編譯錯誤,也可以在擴展中使用final關鍵字。
可以在類定義中的class關鍵字之前添加final修飾符防止該類被子類化,任何試圖子類化標記為final的類都將報告編譯錯誤。