创建了父类(super class) Car 和子类 Jaguar。子类中的函数 info() -> Void 覆盖了父类(super class)的函数。已创建类型为 Jaguar 的名为 theAuto 的实例。
问题:
似乎我无法将 theAuto 转换为 Car 类型,请查看代码片段及其注释
class Car {
func info() {
print("You've got a car")
}
}
class Jaguar : Car {
override func info() {
print("You've got a Jaguar")
}
}
let theAuto = Jaguar()
theAuto.info() // --> You've got a Jaguar
let auto = theAuto as Car // casting but seems not working
auto.info() // --> You've got a Jaguar
print(type(of: auto)) // fail to casting
问题:
我想我没有完全理解与覆盖场景一起转换的概念。为什么我不能化妆?覆盖操作是否限制了我的上层类型转换?
非常感谢您的帮助和时间
最佳答案
因为您要覆盖子类中的方法,所以您将获得动态 分派(dispatch)。要调用的方法实现将基于调用它的实例的动态类型。将 Jaguar
升级为 Car
只会更改实例的 static 类型——动态类型仍然是 Jaguar
,因为这是您创建的实例类型。
因此,向上转型对方法的动态分配没有任何影响——也不应该,因为动态分配的全部要点是确保调用给定实例的正确方法实现无论如何 它的静态类型是什么。
您期望的行为类型是静态 分派(dispatch)——编译器根据实例的静态类型选择要调用的实现。这通常通过重载(而不是覆盖)函数来实现。
例如,一个重载的static
方法:
class Car {
static func info(for car: Car) {
print("You've got a Car")
}
}
class Jaguar : Car {
static func info(for jaguar: Jaguar) {
print("You've got a Jaguar")
}
}
let jaguar = Jaguar()
Jaguar.info(for: jaguar) // You've got a Jaguar
Car.info(for: jaguar) // You've got a Car
let car = jaguar as Car
Jaguar.info(for: car) // You've got a Car
在这里,编译器根据调用对象的静态类型和传递的参数来决定要调用哪个 info(for:)
实现。如果它在 Car
上调用,或者传递的参数静态类型为 Car
,则只有 Car
的重载可能被静态分派(dispatch)到.
静态分派(dispatch)的另一个示例是协议(protocol)扩展,其中该方法不是协议(protocol)要求(因为将其作为要求会赋予它动态分派(dispatch))。
protocol Car {}
extension Car {
func info() {
print("You've got a Car")
}
}
class Jaguar : Car {
func info() {
print("You've got a Jaguar")
}
}
let jaguar = Jaguar()
jaguar.info() // You've got a Jaguar
let car = jaguar as Car
car.info() // You've got a Car
在这里,编译器仅根据调用它的实例的静态类型来决定调用 info()
的哪个实现。
关于swift - 当子类中有覆盖函数时如何转换为父类(super class),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43138320/