Polymorphism in java: Why do we set parent reference to child object?

11,854

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.

Share:
11,854
Subhadeep Banerjee
Author by

Subhadeep Banerjee

Updated on June 04, 2022

Comments

  • Subhadeep Banerjee
    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
    MD Sayem Ahmed over 8 years
    Wow, 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
    Raghavendra over 8 years
    pls improve this answer with better english thank you.
  • Raghavendra
    Raghavendra over 8 years
    no idea. i have a doubt why the answer is blinking?
  • Suresh Atta
    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
    Subhadeep Banerjee over 8 years
    The 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
    Marco13 over 8 years
    I have no idea why the .... this was downvoted. It was at least as clear and IMHO more spot-on than other answers.
  • Subhadeep Banerjee
    Subhadeep Banerjee over 8 years
    Marko, 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
    Subhadeep Banerjee over 8 years
    First 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
    Subhadeep Banerjee over 8 years
    @Vicky, Can you elaborate, using the code I've provided above?
  • Suresh Atta
    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
    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 in ArrayList and those which are not available in LinkedList
  • CaTalyst.X
    CaTalyst.X over 8 years
    So, 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
    Raghavendra over 8 years
    @SubhadeepBanerjee it is in my answer. see the 3rd, 4th line
  • dbustosp
    dbustosp almost 7 years
    Actually, you can access to methods in child classes using DownCasting.