Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do we need Downcasting really? [duplicate]

Tags:

java

downcast

I am trying to figure out why do I need Downcasting. I reread my notes from collage and found the below example.

class Student {...}

class Graduate exteds Student {
   getResearchTopic(){...} // this method only exists in Graduate class.
}

We have a ref to Student class and want to access to getResearchTopic method;

Student s1 = new Graduate();
if(s1 instanceof Graduate){
   ((Graduate)s1).getResearchTopic();
}

Great example for Downcasting hah? My question is Why not declare s1 as a Graduate in the first place? Is there a real life example where I will have to downcast instead of using an instance of actual class?

like image 607
b4da Avatar asked Jul 16 '13 19:07

b4da


People also ask

Why do we need downcasting?

Downcasting is useful when the type of the value referenced by the Parent variable is known and often is used when passing a value as a parameter. In the below example, the method objectToString takes an Object parameter which is assumed to be of type String.

What is the purpose of downcasting in Java?

Downcasting is another form of object type casting and is used in appointing the subclass reference object to the parent class that is not allowed in Java.

Why downcasting is not allowed?

Downcasting is not allowed without an explicit type cast. The reason for this restriction is that the is-a relationship is not, in most of the cases, symmetric. A derived class could add new data members, and the class member functions that used these data members wouldn't apply to the base class.

Where is downcasting used in selenium?

Downcasting : Downcasting is to put the child class object reference ID back into child class object by using the parent class referene variable. Upcasting is required for downcasting. Main use of downcasting is that we can access child class method too from single object.


2 Answers

Well, you could have declared the reference s1 to be of type Graduate. The main benefit you get by declaring the reference of super type, is the power of polymorphism.

With a super type reference, pointing to a sub class object, you can bind the same reference to multiple sub class objects. And the actual method invoked will be decided at runtime, based on what object is being pointed to. But, the main condition for this is, that method should also be defined in the subclass, else the compiler will fail to find the method declaration.

Here, you were forced to downcast, because you haven't defined the method in the super class. As compiler cannot see the definition of that method in Student class. It has no idea about what the actual object s1 points to. Remember, compiler only checks the reference type to find the meethod declaration.

In general, whenever you see yourself downcasting to a subclass in your code, it is almost always a sign a something wrong (there are some exceptions though). And you should modify your classes.


Let's see what benefit you get by using a super class reference instead of a subclass reference:

For e.g: Suppose you have another sub class of Student as:

class Phd extends Student {
    getResearchTopic(){...}
}

and you also provide a definition (a default one) in Student class:

class Student {
    getResearchTopic(){...}
}

Now, you create a following two objects, both being pointed to by Student reference:

Student student = new Phd();
student.getResearchTopic();   // Calls Phd class method

student = new Graduate();
student.getResearchTopic();    // Calls Graduate class method

So, with only a single reference, you get to access methods specific to subclasses.


One major implementation of this feature you can see in factory method pattern, where a single static method returns an object of different sub classes based on some condition:

public static Student getInstance(String type) {
    if (type.equals("graduate")) 
        return new Graduate();
    else if (type.equals("phd"))
        return new Phd();
}

So, you can see that the same method returns an object of different subclasses.

All of the above stuffs you can do just because of one concept:

A Super class reference can refer to any sub class objects, but not vice-versa.

like image 113
Rohit Jain Avatar answered Oct 17 '22 05:10

Rohit Jain


Say you have a method that takes a Student as a parameter. Most of the things it does are generic for all students. But if it is a Graduate there might be something else it does as well. In that case you would need to determine if the Student passed in was actually a Graduate and do some special logic in that instance.

Maybe something like this:

class StudentDAO {
    public void SaveStudent(Student s) {
       // Do something to save the student data to a database.

       if ( s instanceof Graduate ) {
           // Save their research topic too.
       }
    }
}

Note that doing that kind of thing is usually a poor programming practice, but sometimes it makes sense.

like image 33
Eric Petroelje Avatar answered Oct 17 '22 06:10

Eric Petroelje