在Swift中,有人能解释如何用原始属性的另一个子类对象覆盖超类上的属性吗?

举个简单的例子:

class Chassis {}
class RacingChassis : Chassis {}

class Car {
    let chassis = Chassis()
}
class RaceCar: Car {
    override let chassis = RacingChassis() //Error here
}

这就产生了错误:

Cannot override with a stored property 'chassis'

如果将机箱改为"var",则会出现以下错误:

Cannot override mutable property 'chassis' of type 'Chassis' with covariant type 'RacingChassis'

在指南的"Overriding Properties"下,我能找到的唯一一件事是,我们必须重写getter和setter,这可能有助于更改属性的值(如果是'var'),但是更改属性类呢?

推荐答案

Swift不允许您更改任何变量或属性的类类型.相反,您可以在处理新类类型的子类中创建一个额外变量:

class Chassis {}
class RacingChassis : Chassis {}

class Car {
    var chassis = Chassis()
}
class RaceCar: Car {
    var racingChassis = RacingChassis()
    override var chassis: Chassis {
        get {
            return racingChassis
        }
        set {
            if let newRacingChassis = newValue as? RacingChassis {
                racingChassis = newRacingChassis
            } else {
                println("incorrect chassis type for racecar")
            }
        }
    }
}

似乎不能用let语法声明一个属性,并在其子类中用var重写它,反之亦然,这可能是因为超类实现可能不希望该属性在初始化后发生更改.因此,在这种情况下,属性需要在超类中用'var'声明,以匹配子类(如上面的代码片段所示).如果无法更改超类中的源代码,那么最好销毁当前的赛车,并在每次需要修改底盘时创建新的赛车.

Swift相关问答推荐

什么是Swift Concurrency中任务组的正常退出

Swift 5.10:无法从非隔离的deinit访问属性*,这是Swift 6中的错误''''

.onReceive NSWindow.CloseNotify是否会为App中的每个窗口调用?

避免嵌套导航TabView

有没有一种方法可以迭代可编码的代码(例如,JSON解析中的每一项)?

声明一个协议时使用和不使用任何单词有什么区别?

无法创建MKAssociateRegion对象

如何使泡泡上的箭头直达封闭矩形

按数组大小进行类型判断?

使用索引来访问 libc 定义的元组

SwiftUI路径平滑连接两条线

如何在类中打印函数

使用 Async-Await 和 Vapor-Fluent 创建 CRUD 函数 - Swift 5.6

XCUITest 在 TearDown 期间随机失败-无法终止 com.bundle.id

将基于MyProtocol的泛型函数的参数更改为使用存在的any MyProtocol或some MyProtocol是否会受到惩罚?

如何自己快速编写 Hashable 协议

EXC_BREAKPOINT 崩溃的原因范围

在 UItextfield 的右视图上添加一个按钮,文本不应与按钮重叠

如何更改弹出框的大小

在 unwind segue 之后执行 push segue