Swift

Swift基础语法(八)继承

2022-05-14  本文已影响0人  iOS之文一

Swift基础语法文章汇总

Swift的继承与其他语言并无两样,本文主要把重写进行了说明,主要是方法/下标重写、属性重写、属性观察器重写,其实他们的本质也就是方法重写。

主要内容:

  1. 方法/下标重写
  2. 属性重写
  3. 属性观察器重写

1、继承认识

继承概念没区别,都是父类子类的关系,也没必要赘言了
这里只看下内存结构

代码:

/*
 1、内存结构
 */
func test1() {
    class Animal {
        var age = 0
    }
    class Dog : Animal {
        var weight = 0
    }
    class ErHa : Dog {
        var iq = 0
    }
    
    //父类
    let a = Animal()
    a.age = 10
    // 32
    print(Mems.size(ofRef: a))
    /*
     0x00000001000073e0
     0x0000000000000002
     0x000000000000000a
     0x0000000000000000
     */
    print(Mems.memStr(ofRef: a))
    
    //子类
    let d = Dog()
    d.age = 10
    d.weight = 20
    // 32
    print(Mems.size(ofRef: d))
    /*
     0x0000000100007490
     0x0000000000000002
     0x000000000000000a
     0x0000000000000014
     */
    print(Mems.memStr(ofRef: d))
    
    //孙子类
    let e = ErHa()
    e.age = 10
    e.weight = 20
    e.iq = 30
    // 48
    print(Mems.size(ofRef: e))
    /*
     0x0000000100007560
     0x0000000000000002
     0x000000000000000a
     0x0000000000000014
     0x000000000000001e
     0x0000000000000000
     */
    print(Mems.memStr(ofRef: e))
    
}
test1()

说明:

  1. 父类继承过来的存储属性是放在前面的
  2. 子类继承父类的存储属性是拷贝到子类中的

2、重写

子类可以重写父类的属性、下标、方法,重写必须加上override关键字(required不需要),需要注意的是不管是方法、下标、属性、属性观察器,所有的重写本质都是函数重写

2.1 方法/下标

下标其实就是方法,所以放到一起写

2.1.1 实例方法

代码:

/*
 2、下标、方法重写
 */
func test2() {
    class Animal {
        func speak() {
            print("Animal speak")
        }
        subscript(index: Int) -> Int {
            return index
        }
    }
    
    class Cat : Animal {
        //方法重写
        override func speak() {
            super.speak()
            print("Cat speak")
        }
        //下标重写
        override subscript(index: Int) -> Int {
            return super[index] + 1
        }
    }
    
    let cat: Animal = Cat()
    cat.speak()
    print(cat[1])
}
test2()

说明:

2.1.2 类型方法

代码:

/*
 2、下标、方法重写
 */
func test2() {
    class Animal {
        class func speak() {
            print("Animal speak")
        }
        class subscript(index: Int) -> Int {
            return index
        }
    }
    
    class Cat : Animal {
        //方法重写
        override class  func speak() {
            super.speak()
            print("Cat speak")
        }
        //下标重写
        override class  subscript(index: Int) -> Int {
            return super[index] + 1
        }
    }
    Cat.speak()
    print(Cat(2))
}
test2()

说明:

2.2 属性

属性本身是没有重写的,只有继承,但是在Swift中有计算属性和属性观察器这两种东西,他们本质上也是函数,所以这两种也可以重写

属性重写的种类:

  1. 计算属性重写为计算属性;
  2. 存储属性重写为计算属性;
  3. 存储属性重写成带有属性观察器的存储属性

代码:

/*
 3、属性重写
 */
func test3() {
    class Circle {
        var radius: Int = 0
        var diameter: Int {
            set {
                print("Circle setDiameter")
                radius = newValue / 2
            }
            get {
                print("Circle getDiameter")
                return radius * 2
            }
        }
    }
    class SubCircle : Circle {
        override var radius: Int {
            set {
                print("SubCircle setradius")
                super.radius = newValue > 0 ? newValue : 0
            }
            get {
                print("SubCircle getradius")
                return super.radius
            }
        }
        
        override var diameter: Int {
            set {
                print("SubCircle setDiameter")
                super.diameter = newValue > 0 ? newValue : 0
            }
            get {
                print("SubCircle getDiameter")
                return super.diameter
            }
        }
    }
    let circle = SubCircle()
    
    //SubCircle setradius
    circle.radius = 6
    
    /*
     SubCircle getDiameter
     Circle getDiameter
     SubCircle getradius
     12
     */
    print(circle.diameter)
    
    //SubCircle setDiameter
    circle.diameter = 20
    
    /*
     SubCircle setDiameter
     Circle setDiameter
     SubCircle setradius
     SubCircle getradius
     10
     */
    print(circle.radius)
}
test3()

说明:

  1. 仅仅只是普通的重写,没什么特殊的
  2. 只是需要注意在调用circle.diameter时,调用一下父类的getDiameter方法,因为在子类的getDiameter方法中会调用super的diameter

注意:

2.3 属性观察器

可以在子类中为父类属性增加属性观察器,此时也需要使用override修饰

代码:

/*
 4、属性观察器重写
 */
func test4() {
    class Circle {
        var radius: Int = 1
    }
    class SubCircle : Circle {
        override var radius: Int {
            willSet {
                print("SubCircle willSetRadius",newValue)
            }
            didSet {
                print("SubCircle didSetRadius",oldValue,radius)
            }
        }
    }
    let circle = SubCircle()
    /*
     SubCircle willSetRadius 10
     SubCircle didSetRadius 1 10
     */
    circle.radius = 10
}
test4()

说明:

  1. let属性、只读计算属性不能增加属性观察器
  2. 如果是给父类的存储属性增加属性观察器,那么子类中只会继承父类的存储属性,没有变成计算属性。仅仅是增加了属性观察器
  3. 如果父类的存储属性也有属性观察器,子类也是可以重写的
  4. 也可以给父类的计算属性重写属性观察器

3、总结

注意:

总结:

  1. 重写除了一般的方法重写,还有下标重写、属性重写、属性观察器重写
  2. 其中下标、属性观察器、计算属性的重写本质上都是属于方法重写
  3. 只是注意一点可以将存储属性重写为计算属性
上一篇下一篇

猜你喜欢

热点阅读