Superclass reference not able to call subclass method in Java

inheritance, java, polymorphism

Solution

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.

Problem

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** } } ```

Original source