继承

作者: Stago | 来源:发表于2020-05-15 11:08 被阅读0次

继承(Inheritance)

  • 值类型(枚举、结构体)不支持继承,只有类支持继承

  • 没有父类的类,称为:基类

  • Swift并没有像OC、Java那样的规定:任何类最终都要继承自某个基类

Note:
Swift classed do not inherit from a universal base class.Classes you define specifying a superclass automatically become base classes for you to build upon.

  • 子类可以重写父类的下标、方法、属性,重写必须加上override关键字

内存结构

class Animal {
    var age = 0
}
class Dog: Animal {
    var weight = 0
}
class Erha: Dog {
    var iq = 0
}
let a = Animal()
a.age = 10
print(Mems.size(ofRef: a))
print(Mems.memStr(ofRef: a))

/*
 32
 0x00000001000073e8
 0x0000000000000002
 0x000000000000000a
 0x0000000000000023
 */

let d = Dog()
d.age = 10
d.weight = 20
print(Mems.size(ofRef: d))
print(Mems.memStr(ofRef: d))

/*
 32
 0x0000000100007498
 0x0000000000000002
 0x000000000000000a
 0x0000000000000014
 */
let e = Erha()
e.age = 10
e.weight = 20
e.iq = 30
print(Mems.size(ofRef: e))
print(Mems.memStr(ofRef: e))

/*
 48
 0x0000000100007568
 0x0000000000000002
 0x000000000000000a
 0x0000000000000014
 0x000000000000001e
 0x0000000100566500
 */

重写实例方法、下标

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
    }
}

var animal: Animal
animal = Animal()
animal.speak()
print(animal[6])

animal = Cat()
animal.speak()
print(animal[6])

/*
 Animal speak
 6
 Animal speak
 Cat speak
 7
 */

重写类型方法、下标

  • 被class修饰的类型方法、下标,允许被子类重写
  • 被static修饰的类型方法、下标,不允许被子类重写
class Animal {
    class func speak() {
        print("Animal speak")
    }
    class subscript(index: Int) -> Int {
        return index
    }
}

Animal.speak()
print(Animal[6])

/*
 Animal speak
 6
 */
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[6])
/*
 Animal speak
 Cat speak
 7
 */

重写属性

  • 子类可以将父类的属性(存储、计算)重写为计算属性

  • 子类不可以将父类属性重写为存储属性

  • 只能重写var属性,不能重写let属性

  • 重写时,属性名、类型要一致

  • 子类重写后的属性权限 不能小于 父类属性的权限

如果父类属性是只读的,那么子类重写后的属性可以是只读的、也可以是可读写的

如果父类属性是可读写的,那么子类重写后的属性必须是可读写的

重写实例属性

class Circle {
    var radius: Int = 0
    var diameter:Int {
        set {
            print("Circle setDiameter")
            radius = newValue / 2
        }
        get {
            print("Circle getDiameter")
            return radius * 2
        }
    }
}

var circle: Circle
circle = Circle()
circle.radius = 6
print(circle.diameter)
circle.diameter = 20
print(circle.radius)

/*
 Circle getDiameter
 12
 Circle setDiameter
 10
 */

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
        }
    }
}

var circle = SubCircle()
circle.radius = 6
print(circle.diameter)

circle.diameter = 20
print(circle.radius)

/*
SubCircle setRadius
 
SubCircle getDiameter
Circle getDiameter
SubCircle getRadius
12
 
SubCircle setDiameter
 
Circle setDiameter
SubCircle setRadius
SubCircle getRadius
10
*/
  • 被class修饰的计算类型属性,可以被子类重写
  • 被static修饰的类型属性(存储、计算),不可以被子类重写
class Circle {
    static var radius: Int = 0
    class var diameter: Int {
        set {
            print("Circle setDiameter")
            radius = newValue / 2
        }
        get {
            print("Circle getDiameter")
            return radius * 2
        }
    }
}

class SubCircle: Circle {
    override static var diameter: Int {
        set {
            print("SubCircle setDiameter")
            super.diameter = newValue > 0 ? newValue : 0
        }
        get {
            print("SubCircle getDiameter")
            return super.diameter
        }
    }
}

Circle.radius = 6
print(Circle.diameter)
Circle.diameter = 20
print(Circle.radius)

SubCircle.radius = 6
print(SubCircle.diameter)
SubCircle.diameter = 20
print(SubCircle.radius)

/*
 Circle getDiameter
 12
 Circle setDiameter
 10
 SubCircle getDiameter
 Circle getDiameter
 12
 SubCircle setDiameter
 Circle setDiameter
 10
 */

属性观察器

  • 可以在子类中为父类属性(除了只读计算属性、let属性)增加属性观察器
class Circle {
    var radius: Int = 1
}
class SubCircle: Circle {
    override var radius: Int {
        willSet {
            print("SubCircle willSetRadius", newValue)
        }
        didSet {
            print("SubCircle didSetRadius", oldValue, radius)
        }
    }
}
var circle = SubCircle()
circle.radius = 10

/*
 SubCircle willSetRadius 10
 SubCircle didSetRadius 1 10
 */
class Circle {
    var radius: Int = 1 {
        willSet {
            print("Circle willSetRadius", newValue)
        }
        didSet {
            print("Circle didSetRadius", oldValue, radius)
        }
    }
}
class SubCircle: Circle {
    override var radius: Int {
        willSet {
            print("SubCircle willSetRadius", newValue)
        }
        didSet {
            print("SubCircle didSetRadius", oldValue, radius)
        }
    }
}
var circle = SubCircle()
circle.radius = 10

/*
 SubCircle willSetRadius 10
 Circle willSetRadius 10
 Circle didSetRadius 1 10
 SubCircle didSetRadius 1 10
 */
class Circle {
    var radius: Int {
        set {
            print("Circle setSetRadius", newValue)
        }
        get {
            print("Circle getRadius")
            return 20
        }
    }
}
class SubCircle: Circle {
    override var radius: Int {
        willSet {
            print("SubCircle willSetRadius", newValue)
        }
        didSet {
            print("SubCircle didSetRadius", oldValue, radius)
        }
    }
}
var circle = SubCircle()
circle.radius = 10

/*
 Circle getRadius
 SubCircle willSetRadius 10
 Circle setSetRadius 10
 Circle getRadius
 SubCircle didSetRadius 20 20
 */
class Circle {
    class var radius: Int {
        set {
            print("Circle setSetRadius", newValue)
        }
        get {
            print("Circle getRadius")
            return 20
        }
    }
}
class SubCircle: Circle {
    override static var radius: Int {
        willSet {
            print("SubCircle willSetRadius", newValue)
        }
        didSet {
            print("SubCircle didSetRadius", oldValue, radius)
        }
    }
}

SubCircle.radius = 10

/*
 Circle getRadius
 SubCircle willSetRadius 10
 Circle setSetRadius 10
 Circle getRadius
 SubCircle didSetRadius 20 20
 */

final

  • 被final修饰的方法、下标、属性,禁止被重写
  • 被final修饰的类,禁止被继承

相关文章

  • 继承 继承

    属性拷贝 继承不单单能通过原型链实现,也能通过其他方式实现,属性拷贝就是其中一种方法。 通过属性拷贝也能实现继承子...

  • 继承(单继承,多继承)

    将共性的内容放在父类中,子类只需要关注自己特有的内容 python中所有的内容都是对象,所有的对象都直接或间接继承...

  • js继承方式

    类式继承 构造函数继承 组合继承 类式继承 + 构造函数继承 原型式继承 寄生式继承 寄生组合式继承 寄生式继承 ...

  • Python-学习之路-08 OOP -02

    单继承和多继承 单继承:每个类只能继承一个类 多继承:每个类可以继承多个类 单继承的多继承的优缺点 菱形继承/钻石...

  • 原型相关(二)

    1.继承 继承方式:接口继承(只继承方法签名)实现继承(继承实际的方法)ECMAScript只支持实现继承,并且主...

  • 继承

    继承的引入和概述 继承案例和继承的好处 继承的弊端 Java中继承的特点 继承的注意实现和什么时候使用继承 继承中...

  • Java面向对象三大特性之继承

    继承 一、继承的特点 Java只支持单继承单继承 多继承 单继承、多继承优缺点①单继承优点:提高了代码的复用性,让...

  • 7、面向对象的程序设计3(《JS高级》笔记)

    三、继承 许多OO语言都支持两种继承方式:接口继承和实现继承。接口继承只继承方法签名,而实现继承则继承实际方法。由...

  • 【重学前端】JavaScript中的继承

    JavaScript中继承主要分为六种:类式继承(原型链继承)、构造函数继承、组合继承、原型式继承、寄生式继承、寄...

  • js之继承

    文章主讲 JS 继承,包括原型链继承、构造函数继承、组合继承、寄生组合继承、原型式继承、 ES6 继承,以及 多继...

网友评论

      本文标题:继承

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