当子类中有覆盖函数时,如何转换为超类 [英] how to cast up to super class when there is an override function in the sub class

查看:40
本文介绍了当子类中有覆盖函数时,如何转换为超类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

已创建超类 Car 和子类 Jaguar .子类中的函数 info()->无效 覆盖了超类的函数.已创建类型为 Jaguar 的名为 theAuto 的实例.

A super-class Car and a sub-class Jaguar was created. The function info() -> Void in the sub-class overrided the super-class' function. A instance named theAuto of type Jaguar had been created.

问题:

似乎我无法将 theAuto 强制转换为 Car 类型,请参见代码段及其注释

Seems I cannot up casts the theAuto to the type of Car, please see the code snippet and its comments

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

问题:

我认为我不完全了解将覆盖和替代方案一起使用的概念.为什么我不能补编?超越动作会限制我的上风吗?

I think I didn't fully understand the concept of casting together with override scenario. Why I cannot make the up casting? Is the override action limited my upper casting?

非常感谢您的帮助和时间

many thanks for your help and time

推荐答案

由于您正在覆盖子类中的方法,因此将获得 dynamic 调度.调用的方法实现将基于其调用实例的动态类型.将 Jaguar 上载到 Car 只会更改实例的 static 类型-动态类型仍然是 Jaguar ,因为这就是您创建的实例的类型.

Because you're overriding the method in a subclass, you're getting dynamic dispatch. The method implementation to call will be based on the dynamic type of the instance that it's called on. Upcasting a Jaguar to a Car only changes the static type of the instance – the dynamic type is still a Jaguar, for that's the type of instance you created.

因此,向上转换对方法的动态分配完全没有影响,也不应该这样做,因为动态分配的全部目的是确保对给定实例的正确方法实现称为 它的静态类型是什么.

Therefore upcasting has no bearing whatsoever on the dynamic dispatch of a method – nor should it, as the whole point of dynamic dispatch is to ensure that the correct method implementation for the given instance is called no matter what it's statically typed as.

您期望的行为是 static 分派–编译器根据实例的静态类型选择要调用的实现.这通常是通过重载(而不是覆盖)功能来实现的.

The kind of behaviour you're expecting is static dispatch – the compiler chooses the implementation to call based on the static type of the instance. This is commonly achieved by overloading (rather than overriding) functions.

例如,重载的 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 的重载可以静态分配给

Here, the compiler resolves which implementation of info(for:) to call based on the static types of what it's being called on and the arguments being passed. If it's either called on Car, or the argument passed is statically typed as a Car, only Car's overload can possibly be statically dispatched to.

静态分配的另一个示例是协议扩展,该方法不是协议要求(因为将其作为要求可以动态分配).

Another example of static dispatch is with a protocol extension, where the method isn't a protocol requirement (as making it a requirement gives it dynamic 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()实现.

Here, the compiler resolves which implementation of info() to call solely based on the static type of the instance that it's called on.

这篇关于当子类中有覆盖函数时,如何转换为超类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆