Swift 5.1 (13) - 繼承

級別: ★☆☆☆☆
標籤:「iOS」「Swift 5.1」「繼承」
做者: 沐靈洛
審校: QiShare團隊php


繼承

繼承是一種基本行爲:子類繼承父類方法,屬性和其餘特性。子類能夠重寫父類的方法,屬性。繼承將類與Swift中的其餘類型區分開來。
類還能夠將屬性觀察者添加到繼承的存儲屬性或計算屬性上。git

定義一個基類

基類:定義的任何不從其餘類繼承的類。Swift中的類在不指定父類的狀況下,是不會從通用基類繼承,這種狀況下構建的類即是開發者定義的基類。github

class BaseClass {
    //....基類的方法,屬性等定義
}
複製代碼

子類

子類:在現父類基礎上構建的新類。子類繼承父類的方法,屬性和其餘特徵,並進行差別化操做。編程

class SubClass: BaseClass {
    //...繼承自`BaseClass`的子類
}
複製代碼

重寫

重寫:子類提供父類的實例方法,類型方法,實例屬性,類型屬性或下標的自定義實現。
重寫的實現方式:子類要覆蓋的繼承父類的特性屬性或方法前使用override關鍵字。
訪問父類的方法,屬性和下標
在重寫父類的方法,屬性和下標時,使用super前綴能夠承繼父類對於方法,屬性和下標的實現。swift

class BaseClass {
    
    //....基類的方法,屬性等定義
    var something: String {
        get {
            return "i from super"
        }
    }
    func doSomething() -> Void {
    }
    subscript(index:Int)->String {
        return "QiShare"
    }
}
class SubClass: BaseClass {
    //...繼承自`BaseClass`的子類
    override var something: String {
        return super.something + "+override" //!< 調用輸出:i from super+override
    }
    override func doSomething() {
        super.doSomething()
    }
    override subscript(index:Int)->String {
        return super[1] + "/subClass" //!< 調用輸出:QiShare/subClass
        
    }
複製代碼

重寫屬性
能夠覆蓋繼承的實例或類型屬性,爲該屬性提供自定義的gettersetter,也能添加屬性觀察者。子類沒法知道繼承的屬性是否計算或存儲屬性,但知道繼承的屬性名稱和類型。故重寫屬性時需明確屬性的名稱和類型。bash

1. 重寫屬性的GetterSetter方法:
關於重寫屬性的GetterSetter,官網描述:微信

You can provide a custom getter (and setter, if appropriate) to override any inherited property, regardless of whether the inherited property is implemented as a stored or computed property at source。譯文:不管繼承的屬性是在父類中是存儲屬性仍是計算屬性,子類均可以提供自定義getter,也能夠在場景適用狀況下提供setter,用以重寫屬性app

可是在實際的操做中發現:
• 繼承自父類的存儲屬性不能被重寫。重寫時報錯:Cannot override with a stored property 'something'。錯誤示範以下:less

//父類聲明常量屬性
let something: String = "QiShare"
//子類重寫常量屬性:報錯:`Cannot override with a stored property 'something'`
override let something: String {
    get {
        return "sub+QiShare"
    }
}
複製代碼

• 繼承自父類的變量屬性,非計算屬性,子類在重寫該屬性時須要同時提供settergetter。不然編譯器報錯:Cannot override mutable property with read-only property 'something'。正確示範以下:ide

//父類聲明變量屬性
var something: String = ""
//或
var something: String?
//子類重寫變量屬性
override var something : String {
    get {
        return "子類的實現"
    }
    set{
    }
}
複製代碼

• 經過重寫計算屬性GetterSetter方法,子類可將繼承自父類的read-only屬性變爲read-write屬性。示例以下:

//父類聲明`read-only`屬性
var something: String {
        get {
            return "i from super"
        }
    }
//子類重寫後變爲`read-write`屬性
private var _temp :String = ""
override var something: String {
    get {
       return super.something + _temp //!< 調用輸出:i from super+override
    }
    set {
        _temp = newValue + "subClass override setter"
    }
}
//實際調用,確實如此
let base = BaseClass()
//base.something = "這句話會報錯,由於`sothing`在基類中是隻讀屬性"
let sub = SubClass()
sub.something = "子類重寫後" //!< i from super子類重寫後subClass override setter
複製代碼

• 經過重寫計算屬性GetterSetter方法,不能將繼承自父類的read-write屬性變爲read-only。我的理解:子類能夠增長屬性功能,但不能減小屬性功能。反其道而行之,編譯器報錯:Cannot override mutable property with read-only property 'something'

• 計算屬性無論是read-write仍是read-only都須要使用var關鍵字來聲明爲變量屬性。計算屬性在組成上由getter和一個可選的setter組成的,即:無論setter有沒有,getter都必須有。也所以,如果咱們重寫了setter方法則必須重寫getter方法。基於這種狀況getter方法的重寫,有時是基於語法的組合體,本質上其實和父類是同樣的,那麼咱們即可以在getter方法中使用super前綴來承繼父類的調用。

2. 重寫屬性的觀察者:
• 屬性可觀察的前提是該屬性是可變的,故不能在繼承的存儲屬性和read-only屬性中添加willSetdidSet。反其道而行之,實際操做中編譯器也會報錯:Cannot observe read-only property 'something'; it can't change
• 繼承的read-write屬性,不能重寫setter方法的同時,重寫或者添加屬性觀察器。反其道而行之,在實際操做中編譯器會報錯:didSetwillSet cannot be provided together with a settergetter

防止重寫

使用final關鍵字防止方法,屬性或下標被子類重寫。具體使用:final varfinal funcfinal class funcfinal subscript

  • 父類使用final關鍵字修飾過的方法,屬性或下標,子類重寫時編譯器便會報錯。
  • 在類擴展中使用final關鍵字修飾過的方法,屬性或下標也一樣生效。
  • 在類定義時的class關鍵字以前使用final關鍵字,來將整個類的方法,屬性或下標標記爲子類不可重寫。

參考資料: swift 5.1官方編程指南


小編微信:可加並拉入《QiShare技術交流羣》。

關注咱們的途徑有:
QiShare(簡書)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公衆號)

推薦文章:
WebSocket 雙端實踐(iOS/ Golang)
今天咱們來聊一聊WebSocket(iOS/Golang)
用 Swift 進行貝塞爾曲線繪製
Swift 5.1 (11) - 方法
Swift 5.1 (10) - 屬性
iOS App後臺保活
奇舞週刊

相關文章
相關標籤/搜索