Prasad Kharkar Prasad Kharkar - 1 month ago 5x
Java Question

Superclass method being called even though object is of subclass

I was playing around with simple overloading overriding rules and found something interesting. Here is my code.

package com.demo;

public class Animal {

private void eat() {
System.out.println("animal eating");

public static void main(String args[]) {

Animal a = new Horse();;

class Horse extends Animal {
public void eat() {
System.out.println("Horse eating");

This program outputs the below.

animal eating

Here is what I know:

  • As we have
    private void eat()
    method, it is not definitely going to be accessed in a subclass, so the question of method overriding does not arise here as JLS defines it clearly.

  • Now that this is not method overriding, it is definitely not going to call
    public void eat()
    method from the Horse class

  • Now our declaration
    Animal a = new Horse();
    is valid because of polymorphism.

Why is
invoking a method from the Animal class? We are creating a Horse object, so why does the Animal class' method get called?


I am not sure if I understand your confusion. Based on what you know:

You are right, is not overriding (as it is private). In another word, when you call, no late-binding happens and hence, you are simply calling, which is what you see.

From your other comment, seems that your confusion is how the compiler is deciding what to call. Here is a very high-level explanation:

When compiler sees Animal a =...;;, it will try to resolve what to call.

For example, if it sees eat() is a static method, given a is a reference to Animal, compiler will translate it to call

If it is an instance method, and it encounters a method that may have been overridden by a child class, what the compiler does is, it will not generate instructions to call a specific method. Instead, it will generate instructions to do some kind of lookup from a vtable. Conceptually, each object will have a little table, which the key is the method signature, and the value is the reference to the actual method to call. For example, if in your case, is not private, what Horse's vtable will contain is something like ["eat()" -> ""]. So at runtime, given an Animal reference and eat is called, what happen is actually: lookup from the table with eat(), ok, it is referring to (if it is referring a Horse), so I will call it. This is how the magic of late binding is done in most cases.

With an instance method that is not possible to be overridden, compilers do similar things as static methods and generate instructions to call that method directly.

(The above is not technically accurate, just a conceptual illustration for you to understand what happened)