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.
Problem:
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
Question:
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
Note: In a subclass, you can overload the methods inherited from the superclass. Such overloaded methods neither hide nor override the superclass instance methods—they are new methods, unique to the subclass.
You can try to convert the super class variable to the sub class type by simply using the cast operator. But, first of all you need to create the super class reference using the sub class object and then, convert this (super) reference type to sub class type using the cast operator.
Subclass methods can call superclass methods if both methods have the same name. From the subclass, reference the method name and superclass name with the @ symbol.
Does a superclass have access to the members of a subclass? Does a subclass have access to the members of a superclass? No, a superclass has no knowledge of its subclasses.
Therefore, if you need to make sure that the sub class overrides a particular method of the super class method, you just need to declare the required method abstract. To make the above program work you need to implement all the abstract methods as −
If the methods are present in SuperClass, but overridden by SubClass, it will be the overridden method that will be executed. Second approach (Referencing using subclass reference) : A subclass reference can be used to refer its object.
First approach (Referencing using Superclass reference): A reference variable of a superclass can be used to a refer any subclass object derived from that superclass. If the methods are present in SuperClass, but overridden by SubClass, it will be the overridden method that will be executed.
There are two methods to call the instance variables and methods of the superclass (parent class) in the child class. 1. First Method: super keyword is one of the reserved words in java. Super refers to an object of the parent class. (Refer to this article).
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.
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.
For example, an 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) // 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
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
Here, the compiler resolves which implementation of info()
to call solely based on the static type of the instance that it's called on.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With