Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to cast up to super class when there is an override function in the sub class

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

like image 838
SLN Avatar asked Mar 31 '17 10:03

SLN


People also ask

Can we access super class version of overridden method in the sub class?

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.

Can I cast a superclass to a 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.

Can we call super class method in subclass?

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.

Can I access the sub class methods using a super class object?

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.

How to override a particular method of a super class method?

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 −

What happens if a superclass is overridden by a subclass?

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.

How do you refer to a subclass of a superclass?

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.

How to call the instance variables of the superclass in Java?

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).


1 Answers

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.

like image 139
Hamish Avatar answered Nov 15 '22 06:11

Hamish