Since you are overriding a method in a subclass, you get a dynamic dispatch. The method implementation for the call will be based on the dynamic type of the instance that it called. Upcasting a Jaguar to Car only changes the static type of the instance - the dynamic type is still Jaguar , for this type of instance created.
Therefore, the increase in speed has nothing to do with the dynamic dispatch of the method, nor should it, since the whole point of the dynamic dispatch should ensure that the correct implementation of the method for this instance is called regardless of what it statically injects.
The type of behavior you expect is static dispatch — the compiler chooses the implementation to invoke based on the static type of the instance. This is usually achieved by overloading (rather than overriding) functions.
For example, the overloaded static method:
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)
Here, the compiler decides which implementation of info(for:) call based on the static types of what it is called on and the arguments passed. If he either called Car , or the argument passed was statically entered as Car , congestion can only be sent to Car .
Another example of static sending is protocol extension, where the method is not a protocol requirement (since this requirement requires dynamic sending).
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
Here, the compiler permits which implementation of info() is called solely on the basis of the static type of the instance that it called.
source share