Search code examples
javainheritancedowncastupcasting

Upcasting/Downcasting in Java


I am trying to understand upcasting and downcasting in Java and I am confused by the following scenario (about my code, which is below):

First - why is it that the code does not compile when I include the line myAnimal.bark();,

and Second - (assuming I comment out myAnimal.bark();) why does calling myAnimal.move() print "moveDog" instead of "moveAnimal"? Isn't myAnimal restricted to methods from the Animal class because we have declared its type to be Animal, even though we are setting it to a type of Dog?

Any help is greatly appreciated! Here is the code:

    public class Animal {
        public void move() {
            System.out.println("moveAnimal");
        }

       public static void main(String[] args) {
          Dog myDog = new Dog();
          Animal myAnimal = myDog;
          myAnimal.move();
          //myAnimal.bark();
       }
    }

    class Dog extends Animal {
        @Override
        public void move() {
           System.out.println("moveDog");
        }

        public void bark() {
            System.out.println("bark");
        }
    }



Solution

  • With the implicit upcast at this line:

    Animal myAnimal = myDog;
    

    You are not doing anything to change the underlying instance myDog. What you are doing is assigning it to a variable of a type one level higher in the inheritance tree. Effectively, this restricts which methods can be called to only those defined in Animal, but does not change how those methods resolve.

    Because you have restricted the methods available to only those defined on the parent class Animal, the compiler cannot resolve Dog#bark(), since it is a method of Dog, and the variable myAnimal is defined to be of type Animal which has no #bark method.

    #move() is a method of both Animal and Dog, so it resolves, but it resolves to the method defined on Dog, since myAnimal still refers to an instance of Dog, despite being upcast.