swift 学习- 14 -- 继承
// 一個類可以繼承另一個 類的方法, 屬性和其他特征, 當一個類繼承其他類時, 繼承類叫子類, 被繼承類叫父類 或 (超類), 在 Swift 中, 繼承是區分 [類] 和其他類型的 一個基本特征
?
// 在 Swift 中, 類可以調用和訪問超類的方法, 屬性 和 下標, 并且可以重寫這些方法, 屬性 和 下標來優化或修改他們的行為
// Swift 會檢查你的重寫定義在超類中是否有匹配的定義, 一次確保你的重寫行為是正確的
?
// 可以為類中繼承來的屬性添加屬性觀察器, 這樣一來, 當屬性值改變時, 類就會被通知到, 可以為 任意屬性 添加 屬性觀察器,無論他原本被定義為 存儲屬性 還是 計算屬性
?
?
?
?
// 定義一個基類
// 不繼承于其他類的類, 稱之為 基類
// 注意 : Swift 中的類并不是 從一個通用的 基類繼承而來, 如果你不為你定義的類指定一個 超類 的話, 這個類就自動成為 基類
?
?
// 一個例子定義了一個叫做 Vehicle 的基類, 這個基類聲明了一個名為 currentSpeed , 默認值是 0.0 的存儲屬性 (屬性類型推斷為 Double), currentSpeed 屬性的值被一個 String 類型的只讀計算型屬性 description 使用, 用來創建車輛的描述 . Vehicle 基類也定義了一個名為 makeNoise 的方法, 這個方法實際上部位 Vehicle 實例做任何事, 但之后將會被 Vehicle 的子類定制
?
class Vehicle{
? ? var currentSpeed = 0.0
? ? var description: String {
? ? ? ? return "traveling at \(currentSpeed) miles per hour"
? ? }
?? ?
? ? func makeNoise() {
? ? ? ? // 什么也不作
? ? }
}
?
?
let someVehicle = Vehicle()
print("Vehicle: \(someVehicle.description)")
?
?
?
?
// 子類生成
// 子類生成 指的是在一個已有類的基礎上創建一個新的類, 子類繼承超類的特性, 并且可以進一步完善, 你還可以為子類添加新的特性
// 為了指明某個類的超類, 將超類名卸載子類名的后面, 用冒號分割:
?
class Bicycle: Vehicle{
? ? var hasBasket = false
}
?
// 新的 Bicycle 類自動獲得 Vehicle 類的所有屬性 和 方法, 除了他所繼承的特性, Bicycle 類還定義了一個默認值為 false 的存儲屬性 hasBasket (Bool 型)
?
// 默認情況下,你創建的任何新的 Bicycle 實例將不會有一個籃子,但是可以為特定的 Bicycle 實例設置 hasBasket 屬性為 ture
?
let bicycle = Bicycle()
bicycle.hasBasket = true
?
// 還可以修改 Bicycle 實例所繼承的 currentSpeed 屬性, 和查詢實例所繼承的 descriotion 屬性:
bicycle.currentSpeed = 15.0
print("Bicycle: \(bicycle.currentSpeed)")
?
?
// 子類還可以繼續被其它類所繼承 下面的示例為Bicycle創建了一個名為Tandem(雙人自行車)的子類:
?
?
class Tandem: Bicycle {
? ? var currentNumberOfPassengers = 0
}
?
?
// Tandem從Bicycle繼承了所有的屬性與方法,這又使它同時繼承了Vehicle的所有屬性與方法。Tandem也增加了一個新的叫做currentNumberOfPassengers的存儲型屬性,默認值為0。
?
?
// 如果你創建了一個Tandem的實例,你可以使用它所有的新屬性和繼承的屬性,還能查詢從Vehicle繼承來的只讀屬性description:
?
?
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"
?
?
?
?
// 重寫
// 子類可以為繼承來的實例方法, 類方法, 實例屬性, 或 下標提供自己定制實現, 我們把這種行為叫做 重寫
?
// 如果要重寫某個特性, 你需要在重寫定義的前面加上 override 關鍵字, 這么做, 你就表明了你是想提供一個重寫版本, 而非錯誤地提供一個相同的定義, 意外的重寫可能導致 不可預知的 錯誤, 任何缺少 override 關鍵字的 重寫都會在編譯時診斷為 錯誤
?
// override 關鍵字會提醒 Swift 編輯器去檢查該類的 超類,是否有匹配重寫版本的聲明, 這個檢查可以確保你的重寫定義是正確的
?
?
?
?
// 訪問超類的方法, 屬性 和 下標
// 當你在子類中重寫超類的方法,屬性 或 下標時, 有時 在你的重寫版本中 使用已經存在的 超類實現 會大有裨益, 比如, 你完全可以完善已有實現的行為, 或在一個繼承來的變量中存儲一個修改過的值
?
// 在適當的地方, 你可以通過使用 super 前綴來訪問超類版本的方法, 屬性 或 下標
// 1:? 在方法someMethod()的重寫實現中,可以通過super.someMethod()來調用超類版本的someMethod()方法。
// 2:? 在屬性someProperty的 getter 或 setter 的重寫實現中,可以通過super.someProperty來訪問超類版本的someProperty屬性。
// 3:? 在下標的重寫實現中,可以通過super[someIndex]來訪問超類版本中的相同下標。
?
?
?
?
// 重寫方法
// 在子類中, 你可以重寫繼承來的實例方法或類方法, 提供一個定制或替代的方法實現
?
class Train: Vehicle{
? ? override func makeNoise() {
? ? ? ? print("Choo Choo")
? ? }
}
?
// 這個例子定義了 Vehicle 的一個新的子類, 叫 Train, 它重寫了從 Vehicle 類繼承來的 makeNoise() 方法
?
let train = Train()
train.makeNoise()
?
?
?
?
// 重寫屬性
// 你可以重寫繼承來的實例屬性或類型屬性, 提供自己定制的 getter 和 setter,或添加屬性觀察器 使 重寫的屬性 也可以觀察值什么時候變化
?
?
?
// 重寫 屬性的 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)"
? ? }
}
?
// 這個例子定義了一個新類,叫Car,它是Vehicle的子類。這個類引入了一個新的存儲型屬性叫做gear,默認值為整數1。Car類重寫了繼承自Vehicle的description屬性,提供包含當前檔位的自定義描述:
?
// 重寫的 description 屬性首先要調用 super.description 返回 Vehicle 類的 description 屬性 之后, Car 類版本的 description 在末尾增加了自定義內容
?
let car = Car()
car.currentSpeed = 25.0
car.gear = 3
print("Car: \(car.description)")
?
?
?
?
// 重寫屬性觀察器
// 你可以通過重寫屬性為一個 繼承來的 屬性 添加 屬性觀察器, 這樣一來, 當繼承來的屬性值發生變化時, 你就會被通知到, 無論哪個屬性原本是如何實現的
?
// 注意 : 你不可以為繼承來的常量存儲屬性 或 繼承來的只讀計算屬性添加 屬性觀察器, 這些屬性的值是不可以被設置的. 所以, 為他們提供 willSet 和 didSet 是不恰當的
// 此外, 你不可以同時提供重寫的 setter 和 重寫的 屬性觀察器, 如果你想觀察屬性值的變化, 并且你已經為那個屬性提供了定制的 setter ,那么你在 setter 中就可以觀察到任何值的變化了
?
class AutomaticCar: Car{
? ? override var currentSpeed: Double{
? ? ? ? didSet{
? ? ? ? ? ? gear = Int(currentSpeed / 10.0) + 1
? ? ? ? }
? ? }
}
?
// 當你設置 AutomaticCar 的 currentSprrd 屬性, 屬性的 didSet 觀察器就會自動地設置 gear 屬性, 為新的速度選擇一個合適的檔位, 具體來說, 屬性觀察器將新的速度值除以 10 ,然后向下取得最接近的整數值, 最后加 1 來得到檔位 gear 的值,?
?
let automatic = AutomaticCar()
automatic.currentSpeed = 35.0
print("AutomaticCar: \(automatic.description)")
?
?
?
?
// 防止重寫
// 你可以通過把方法,屬性 或 下標標記為 final 來防止他們被重寫, 只需要在聲明關鍵字前 加上 final 修飾符即可
// 如 : final var , final func, final class func , final subscript
?
// 如果你重寫了帶有 final 標記的方法, 屬性或者下標, 在編譯時或報錯,?
?
// 在類擴展中的方法, 屬性 或 下標也可以在擴展的定義里標記為 fnial
?
// 你可以通過在關鍵字 class 前添加 final 修飾符 (final class) 來將整個類標記為 final 的, 這樣的類是不可被繼承的, 試圖繼承這樣的類會導致編譯錯誤
?
轉載于:https://www.cnblogs.com/dingzhijie/p/6897322.html
總結
以上是生活随笔為你收集整理的swift 学习- 14 -- 继承的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Error opening zip fi
- 下一篇: 阿里1582.73亿营收背后的持续交付如