美文网首页
认识Swift系列11之继承

认识Swift系列11之继承

作者: Niuszeng | 来源:发表于2019-07-12 15:41 被阅读0次
        // 值类型(枚举、结构体)不支持继承,只有类才支持继承
        // swift中不想OC、Java中必须继承至某个父类,默认就是基类
        // 子类可重写父类的下标、方法、属性,重写必须加上override关键字
        
        // 1.内存结构
        func test_memory() {
            class Animal {
                var age = 5
                // 打印Animal实例可知,该类占用24个字节
                // 事实上通过详细分析原理得知,该类的实例内存分为三块
                
                /** Animal 实例 内存结构
                 占用3*8=24个字节,由于ios系统分配是以16倍数分配,故分配32个字节
                 ┏━━━━━━━━━━━━━━┓        ┏━━━━━━━━━━━━━━━━━━━━━━┓
                 ┃ classInfo    ┃        ┃ 0x0000000100078e     ┃
                 ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
                 ┃ retainCount  ┃        ┃ 0x00000000000001     ┃
                 ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
                 ┃ var age      ┃        ┃ 0x00000000000005     ┃
                 ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
                 */
            }
            class Dog: Animal {
                var weight = 7
                
                /** Dog 实例 内存结构
                 占用4*8=32个字节,由于ios系统分配是以16倍数分配,故任然分配32个字节
                 ┏━━━━━━━━━━━━━━┓        ┏━━━━━━━━━━━━━━━━━━━━━━┓
                 ┃ classInfo    ┃        ┃ 0x0000000100078e     ┃
                 ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
                 ┃ retainCount  ┃        ┃ 0x00000000000001     ┃
                 ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
                 ┃ var age      ┃        ┃ 0x00000000000005     ┃
                 ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
                 ┃ var weight   ┃        ┃ 0x00000000000007     ┃
                 ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
                 */
            }
            class WhiteDog: Dog {
                var height = 15
                /** Dog 实例 内存结构
                 占用4*8=40个字节,由于ios系统分配是以16倍数分配,故分配48个字节
                 ┏━━━━━━━━━━━━━━┓        ┏━━━━━━━━━━━━━━━━━━━━━━┓
                 ┃ classInfo    ┃        ┃ 0x0000000100078e     ┃
                 ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
                 ┃ retainCount  ┃        ┃ 0x00000000000001     ┃
                 ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
                 ┃ var age      ┃        ┃ 0x00000000000005     ┃
                 ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
                 ┃ var weight   ┃        ┃ 0x00000000000007     ┃
                 ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
                 ┃ var height   ┃        ┃ 0x0000000000000f     ┃
                 ┗━━━━━━━━━━━━━━┛        ┗━━━━━━━━━━━━━━━━━━━━━━┛
                 */
            }
            // 综上
            // swift中的集成结构实际操作为,将父类的存储属性拷贝到子类当中(这里点类似C++)
            // classInfo部分实际上是虚表地址(方法列表)
            // retainCount是引用计数器
        }
        test_memory()
        
        // 2.重写下标、方法
        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("类方法重写-------")
            Animal.speak()
            Dog.speak()
            
            print("实例方法重写-------")
            let a = Animal()
            let d = Dog()
            a.speak()
            d.speak()
            
            print("下标方法重写-------")
            print("---->\(a[0])")
            print("---->\(d[0])")
        }
        test_override_method_subscript()
        
        // 3.重写实例属性
        // 无论父类是存储类型还是计算类型,在子类中重写都职能重写为计算类型
        // 如果是类属性
        //      calss修饰的计算属性可以被子类重写(class只能在类中声名计算属性)
        //      static修饰的存储和计算属性都不可以被子类重写
        //
        // 注意:我们都知道,属性观察期和计算属性不能共存(set、get与willSet、didSet)
        //      但是可以将父类中的计算属性,在子类中重写添加观察器,也可以重写观察器
        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 {}
                }
                
            }
            
            // 重写子类观察器,父类观察器也会被调用
            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个步骤容易理解,主要是第一步,原因是需要先获取到x变量的地址,所以预先getter
             */
        }
        test_override_property()
        
        // final
        func test_final() {
            // 被final修饰的类、方法、下标、属性,禁止被重写
            /** 类
             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 {
                // 都不能重写
            }
        }
        test_final()
    

    相关文章

      网友评论

          本文标题:认识Swift系列11之继承

          本文链接:https://www.haomeiwen.com/subject/zhfykctx.html