Polymorphism in java: Why do we set parent reference to child object?
Solution 1
Okay. I think I got my answer.
public class Polymorphism {
public static void main(String[] args){
Animal obj1 = new Horse();
Horse obj2 = new Horse();
obj1.shout(); //output is neigh..
obj2.shout(); //output is neigh..
obj1.winRaces(); /*But this is not allowed and throws compile time error,
even though the object is of Animal type.*/
}
}
class Animal{
public void shout(){
System.out.println("Parent animal's shout");
}
}
class Horse extends Animal{
public void shout(){
System.out.println("neigh..");
}
public void winRaces(){
System.out.println("won race..");
}
}
So, when we use parent reference for child class object, we cannot access any specific methods in child class (that are not present in parent class) using that object.
Solution 2
Let me code some time.
List<String> list = new ArrayList<String>;
list.doThis();
list.doThat();
Oh wait ..I'm gone mad. I want to use LinkedList
instead of ArrayList
List<String> list = new LinkedList<String>;
list.doThis();
list.doThat();
Yup, I have to change only declaration part. No need to touch all of my code. Thanks to programming to interfaces and with super classes.
Solution 3
This is an implementation of a principle which says -
Program to an interface, not to an implementation.
As an example, if you design a method to accept a reference of type Animal
, then in future you can easily pass an= Cat
implementation to it (provided of course that the Cat
is a sub-type of Animal
.
Which means -
public void doSomethingWithAnimal(Animal animal) {
// perform some action with/on animal
}
is much more flexible than -
public void doSomethingWithAnimal(Dog d) {
// your code
}
because for the first method, you can easily do something like -
doSomethingWithAnimal(new Cat());
if you ever decide to create new Cat
type, inheriting from Animal
.
Solution 4
Think generally, you will know java casting/oop concept.
Dog
is a type of Animal
so you can assign it to an animal.
But you can't assign Animal
to a Dog
. Because it can be any other animal like Cat
. If you are sure the object is Dog
, you can caste that to Animal
. If the Animal
is of type Dog
then you cannot magically cast to a Goat
.
Solution 5
Although there are some good answers (among the "meh" ones), it seems like none was acceptable for you. Maybe they are too theoretical or contain details that you are not interested in. So another try:
For the example that you described, it does not matter. If you really only have a two-line method like
void doit()
{
Animal x = new Dog();
x.shout();
}
then you could also have written
void doit()
{
Dog x = new Dog();
x.shout();
}
and this would not have a direct disadvantage.
One could even generalize this statement: For a reference that is only used locally, it does not matter. When you declare the reference in the method, and only use this reference in this method, and do not pass it to other methods, then there is no direct advantage in declaring it as Animal
instead of as Dog
. You can to both.
But...
even if you are not interested in this, I can't omit it:
... using the parent type is part of a best practice:
You should always use the least specific type that is sufficient for what you want to do
This has various technical reasons, regarding abstraction, generalization, flexibility, the application of polymorphism, and one could even go so far to call it a sort of "type hygiene".
And this explicitly also refers to the case where the reference is only used locally: If you don't want to call methods that are specific for the type Dog
, but only want to call methods from the Animal
class, then you should make this clear by declaring the variable as an Animal
- simply because that's the least specific type that you need. So there is an indirect advantage of using the type Animal
in these cases - namely that it is clear that the following code will only use methods of the Animal
class, and none of the Dog
class.
One could continue and go very far with further justifications, use case examples and technical details here. But for this, you may refer to the other answers, or some intermediate or advanced texbooks and tutorials.
Subhadeep Banerjee
Updated on June 04, 2022Comments
-
Subhadeep Banerjee almost 2 years
I want to understand the use-case of setting a parent reference to a child object. Example: Dog class extends Animal class. (No interfaces, mind it) I would normally create an object of Dog like this:
Dog obj = new Dog();
Now, since Dog is a subclass of Animal it already has access to all of Animal's methods and variables. Then, what difference does this make:
Animal obj = new Dog();
Please provide a proper use-case with an code snippet of its use. No theoretical articles about 'Polymorphism' or 'Coding to interfaces' please!
Code:
public class Polymorphism { public static void main(String[] args){ Animal obj1 = new Dog(); Dog obj2 = new Dog(); obj1.shout(); //output is bark.. obj2.shout(); //output is bark.. } } class Animal{ public void shout(){ System.out.println("Parent animal's shout"); } } class Dog extends Animal{ public void shout(){ System.out.println("bark.."); } } class Lion extends Animal{ public void shout(){ System.out.println("roar.."); } } class Horse extends Animal{ public void shout(){ System.out.println("neigh"); } }
Output is the same for both the cases. Then why do we set parent reference to child object?
-
MD Sayem Ahmed over 8 yearsWow, people are so fast to downvote answers these days. Could someone please point out what did I say in my answer that is wrong? Perhaps I will be able to correct myself and learn something new.
-
Raghavendra over 8 yearspls improve this answer with better english thank you.
-
Raghavendra over 8 yearsno idea. i have a doubt why the answer is blinking?
-
Suresh Atta over 8 years@Reddy When an answer gets -3, it fades away. You seen that. Now someone up voted this and became -2. So you won't see that fade now.
-
Subhadeep Banerjee over 8 yearsThe question is not about why we cannot assign Animal to Dog, but rather why we assign Dog to Animal when we can assign Dog to Dog. Please read my question again!
-
Marco13 over 8 yearsI have no idea why the .... this was downvoted. It was at least as clear and IMHO more spot-on than other answers.
-
Subhadeep Banerjee over 8 yearsMarko, I understand what you're saying. But cat, dog, monkey etc are already subclasses of the Animal type. Hence you can pass any subclass type to the method as well. So why the jugglery with the object reference?
-
Subhadeep Banerjee over 8 yearsFirst thing is List is an interface. My question is more confined to parent & sub classes. Secondly, If you would have used: ArrayList<String> list = new ArrayList<String>(); even then the change would be similar (in one line, 2 places) LinkedList<String> list = new LinkedList<String>(); How much difference does it make?
-
Subhadeep Banerjee over 8 years@Vicky, Can you elaborate, using the code I've provided above?
-
Suresh Atta over 8 years@SubhadeepBanerjee That is why I mentioned in the last.
hanks to programming to interfaces and with super classes.
-
Suresh Atta over 8 years@SubhadeepBanerjee
LinkedList<String> list = new LinkedList<String>();
You are not seeing any change but consider there are few methods added in only inArrayList
and those which are not available inLinkedList
-
CaTalyst.X over 8 yearsSo, you can see the value of the more generic method parameter, but you don't see the value of the type of the actual declaration? Your question is not only poorly articulated, but who cares? It is so pedantic it isn't even worth the effort. If you build an application that has a clear separation between interfaces and implementations, you will use the interface everywhere. You keep making the distinction between parent classes and interfaces, but this is a distinction without a difference.
-
Raghavendra over 8 years@SubhadeepBanerjee it is in my answer. see the 3rd, 4th line
-
dbustosp almost 7 yearsActually, you can access to methods in child classes using DownCasting.