認(rèn)識(shí)Swift系列11之繼承

    // 值類型(枚舉、結(jié)構(gòu)體)不支持繼承,只有類才支持繼承
    // swift中不想OC、Java中必須繼承至某個(gè)父類,默認(rèn)就是基類
    // 子類可重寫(xiě)父類的下標(biāo)、方法、屬性,重寫(xiě)必須加上override關(guān)鍵字
    
    // 1.內(nèi)存結(jié)構(gòu)
    func test_memory() {
        class Animal {
            var age = 5
            // 打印Animal實(shí)例可知,該類占用24個(gè)字節(jié)
            // 事實(shí)上通過(guò)詳細(xì)分析原理得知,該類的實(shí)例內(nèi)存分為三塊
            
            /** Animal 實(shí)例 內(nèi)存結(jié)構(gòu)
             占用3*8=24個(gè)字節(jié),由于ios系統(tǒng)分配是以16倍數(shù)分配,故分配32個(gè)字節(jié)
             ┏━━━━━━━━━━━━━━┓        ┏━━━━━━━━━━━━━━━━━━━━━━┓
             ┃ classInfo    ┃        ┃ 0x0000000100078e     ┃
             ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
             ┃ retainCount  ┃        ┃ 0x00000000000001     ┃
             ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
             ┃ var age      ┃        ┃ 0x00000000000005     ┃
             ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
             */
        }
        class Dog: Animal {
            var weight = 7
            
            /** Dog 實(shí)例 內(nèi)存結(jié)構(gòu)
             占用4*8=32個(gè)字節(jié),由于ios系統(tǒng)分配是以16倍數(shù)分配,故任然分配32個(gè)字節(jié)
             ┏━━━━━━━━━━━━━━┓        ┏━━━━━━━━━━━━━━━━━━━━━━┓
             ┃ classInfo    ┃        ┃ 0x0000000100078e     ┃
             ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
             ┃ retainCount  ┃        ┃ 0x00000000000001     ┃
             ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
             ┃ var age      ┃        ┃ 0x00000000000005     ┃
             ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
             ┃ var weight   ┃        ┃ 0x00000000000007     ┃
             ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
             */
        }
        class WhiteDog: Dog {
            var height = 15
            /** Dog 實(shí)例 內(nèi)存結(jié)構(gòu)
             占用4*8=40個(gè)字節(jié),由于ios系統(tǒng)分配是以16倍數(shù)分配,故分配48個(gè)字節(jié)
             ┏━━━━━━━━━━━━━━┓        ┏━━━━━━━━━━━━━━━━━━━━━━┓
             ┃ classInfo    ┃        ┃ 0x0000000100078e     ┃
             ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
             ┃ retainCount  ┃        ┃ 0x00000000000001     ┃
             ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
             ┃ var age      ┃        ┃ 0x00000000000005     ┃
             ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
             ┃ var weight   ┃        ┃ 0x00000000000007     ┃
             ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
             ┃ var height   ┃        ┃ 0x0000000000000f     ┃
             ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
             */
        }
        // 綜上
        // swift中的集成結(jié)構(gòu)實(shí)際操作為,將父類的存儲(chǔ)屬性拷貝到子類當(dāng)中(這里點(diǎn)類似C++)
        // classInfo部分實(shí)際上是虛表地址(方法列表)
        // retainCount是引用計(jì)數(shù)器
    }
    test_memory()
    
    // 2.重寫(xiě)下標(biāo)、方法
    func test_override_method_subscript() {
        class Animal {
            func speak() {
                print("Animal obj speak")
            }
            
            class func speak() {
                print("Animal speak")
            }
            
            subscript(index: Int)->Int { 10 }
        }
        
        class Dog: Animal {
            override func speak() {
                super.speak()
                print("Dog obj speak")
            }
            
            override class func speak() {
                super.speak()
                print("Dog speak")
            }
            
            override subscript(index: Int) -> Int { super[index] + 20 }
        }
        
        print("類方法重寫(xiě)-------")
        Animal.speak()
        Dog.speak()
        
        print("實(shí)例方法重寫(xiě)-------")
        let a = Animal()
        let d = Dog()
        a.speak()
        d.speak()
        
        print("下標(biāo)方法重寫(xiě)-------")
        print("---->\(a[0])")
        print("---->\(d[0])")
    }
    test_override_method_subscript()
    
    // 3.重寫(xiě)實(shí)例屬性
    // 無(wú)論父類是存儲(chǔ)類型還是計(jì)算類型,在子類中重寫(xiě)都職能重寫(xiě)為計(jì)算類型
    // 如果是類屬性
    //      calss修飾的計(jì)算屬性可以被子類重寫(xiě)(class只能在類中聲名計(jì)算屬性)
    //      static修飾的存儲(chǔ)和計(jì)算屬性都不可以被子類重寫(xiě)
    //
    // 注意:我們都知道,屬性觀察期和計(jì)算屬性不能共存(set、get與willSet、didSet)
    //      但是可以將父類中的計(jì)算屬性,在子類中重寫(xiě)添加觀察器,也可以重寫(xiě)觀察器
    func test_override_property() {
        class A {
            var x: Int = 10
            var y: Int {
                set { x = newValue / 2 }
                get { x * 2 }
            }
            
            static var z = 10
            class var z1: Int {
                set {  }
                get { 10 }
            }
            var f: Int = 10
            var f1: Int {
                set {  }
                get { 10 }
            }
            var f2: Int = 10 {
                willSet {}
                didSet {}
            }
        }
        
        class SubA: A {
            override var x: Int {
                set { super.x = newValue > 0 ? newValue : 0 }
                get { super.x }
            }
            override var y: Int {
                set { super.y = newValue / 3 }
                get { super.y * 3 }
            }
            
            override var f: Int {
                willSet {}
                didSet {}
            }
            override var f1: Int {
                willSet {}
                didSet {}
            }
            override var f2: Int {
                willSet {}
                didSet {}
            }
            
        }
        
        // 重寫(xiě)子類觀察器,父類觀察器也會(huì)被調(diào)用
        class B {
            class var x: Int {
                set { print("B set") }
                get { print("B get"); return 10}
            }
        }
        class SubB: B {
            override class var x: Int {
                willSet { print("B willSet \(newValue)") }
                didSet { print("B didSet \(oldValue), \(x)") }
            }
        }
        SubB.x = 30
        /**
         B get
         SubB willSet 30
         B set
         B get
         SubB didSet 10, 10
         // 后邊4個(gè)步驟容易理解,主要是第一步,原因是需要先獲取到x變量的地址,所以預(yù)先getter
         */
    }
    test_override_property()
    
    // final
    func test_final() {
        // 被final修飾的類、方法、下標(biāo)、屬性,禁止被重寫(xiě)
        /** 類
         final class A {}
         class SubA : A {}
         */
        
        class A {
            final var x: Int = 10
            final var y: Int {
                set {}
                get {10}
            }
            final class var z: Int {
                set {}
                get {10}
            }
        }
        class SubA : A {
            // 都不能重寫(xiě)
        }
    }
    test_final()
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容