Superclass reference not able to call subclass method in Java

I have a basic doubt in polymorphism in Java. I have written the code below in one file named AnimalTestDrive.java. According to me the code below should work specially the line in bold but unfortunately its not. Can you please explain why, I have given the error below:

class Dog extends Animal {

    public void dogMethod() {
        System.out.println("In Dog method");
    }
}

public class AnimalTestDrive {
    public static void main(String args[]) {
        Dog d = new Dog();
        d.dogMethod();
        d.animalMethod();

        Animal animal = new Animal();
        animal.animalMethod();

        animal = d;
        **animal.dogMethod(); // THIS IS NOT WORKING**

    }
}
Jon Skeet
people
quotationmark

Let's try to look at this line the same way that the compiler would:

animal.dogMethod();

First, it needs to work out what animal means. That's nice and easy - it's a local variable in the current method, so it doesn't need to look far.

The compile-time type of that variable is Animal. The compiler doesn't care what the value of the variable will be at execution time - it only uses the information about the declared type.

So, that's what it uses to try to look up what dogMethod() means within the context of animal, i.e. with type Animal. First it looks in Animal, then in java.lang.Object (the implicit superclass of Animal) - but neither of those classes contains a declaration of dogMethod. At that point, the compiler has to give up with an error - it can't find the method. It doesn't matter that the method is available on the execution-time type of the object that the value that animal refers to. It has to bind it at compile-time, using only the information available at compile time.

The only decision made at execution time is which implementation of a method is used - for example, if you called animal.toString() and the Dog class had an override, e.g.

@Override public String toString() {
    return "I'm a dog";
}

then the compiler would find the toString() method from java.lang.Object, so it would know that the method call was valid - but the implementation in Dog would be used because of the execution-time type of the object.

people

See more on this question at Stackoverflow