Swift子类中的Override属性

时间:2019-06-02 01:32:14

标签: swift inheritance properties override

有人可以在继承属性时解释其行为吗?我确信对于“覆盖”实际上没有覆盖属性的解释很好。

为什么Swift允许surname属性被覆盖,但显然仍然使用超类的属性和相关函数?它们不会被覆盖。

似乎我必须定义一些在didSet()方法中调用的函数,并重写该函数以确保子类不像telephone属性那样继承超类的函数。 / p>

是否有任何方法可以覆盖属性的didSet()方法?创建一些被调用的函数似乎会增加不必要的额外复杂性?

实现此目标的正确方法是什么?

import Cocoa

class BaseClass {
    var _name: String?
    var name: String? {
        get {
            return _name
        }
        set {
            _name = newValue
            print("BaseClass \(name)")
        }
    }

    var surname: String? {
        didSet {
            print("BaseClass \(surname)")
        }
    }

    var telephone: String? {
        didSet {
            telephoneSet()
        }
    }

    func telephoneSet(){
        print("BaseClass \(telephone)")
    }
}

class SubClass: BaseClass {
    override var name: String? {
        get {
            return _name
        }
        set {
            _name = newValue
            print("SubClass \(name)")
        }
    }
    override var surname: String? {
        didSet {
            print("SubClass \(surname)")
        }
    }

    override func telephoneSet(){
        print("SubClass \(telephone)")
    }
}


let object = SubClass()

object.name = "Jenny"
object.surname = "Jones"
object.telephone = "10810"

生成以下输出:

SubClass Optional("Jenny")
BaseClass Optional("Jones")
SubClass Optional("Jones")
SubClass Optional("10810")

1 个答案:

答案 0 :(得分:0)

让我们简化您的示例并摆脱不相关的内容:

class BaseClass {
    var surname: String? {
        didSet { print("BaseClass \(surname)") }
    }
}

class SubClass: BaseClass {
    override var surname: String? {
        didSet { print("SubClass \(surname)") }
    }
}

然后:

let object = SubClass()
object.surname = "Jones"

会产生:

  

BaseClass可选(“琼斯”)   
SubClass可选(“琼斯”)

请注意,以上内容并未将存储的属性surname覆盖为另一个存储的属性。它只是基类的存储属性,而您要做的就是让子类向该属性添加观察者。我推荐您使用The Swift Programming Language: Inheritance: Overriding,它说:

  

覆盖属性观察者

     

您可以使用属性覆盖将属性观察器添加到继承的属性。这样一来,无论继承属性的最初实现方式如何,都可以在继承属性的值更改时得到通知。

name的示例中,您用子类自己的计算属性覆盖了计算属性。同样,在您的telephoneSet示例中,您还将用子类自己的方法覆盖该方法。但是使用surname,您并不会覆盖基类的属性,而只是让子类将观察者添加到基类的存储属性中。