javaoverridingmethod-hiding

is the text regarding overriding and hiding methods on docs.oracle.com ambiguous?


I am reading about overriding and hiding methods on the docs.oracle.com website (https://docs.oracle.com/javase/tutorial/java/IandI/override.html). Under the heading 'Static Methods' Oracle kindly summarize for us:

"The distinction between hiding a static method and overriding an instance method has important implications:

The first bullet point is super-clear. The second bullet point also seemed very informative, but as I reread it I seemed to get confused.

From my perspective it seems like that each static methods in both the superclass and subclass are hidden, and by early-binding (compile-time binding) the appropriate method is chosen and the other one is hidden. This is chosen by the reference type of the variable you are calling it from. However the formulation of the sentence in the second bullet point makes it seem like the compiler treat these two methods as one since they have the same signature, and have version super and version sub, contrary to having to separate methods hidden and choosing the appropriate one.

my questions are which of these two angles are correct(both methods hidden or one method with two versions because of the method signature), and does it matter which one I think about? bonus: is my general thoughts on the subject correct?

public class Animal {
    public static void testClassMethod() {
        System.out.println("The static method in Animal");
    }
    public void testInstanceMethod() {
        System.out.println("The instance method in Animal");
    }
}

public class Cat extends Animal {
    public static void testClassMethod() {
        System.out.println("The static method in Cat");
    }
    public void testInstanceMethod() {
        System.out.println("The instance method in Cat");
    }

    public static void main(String[] args) {
        Cat myCat = new Cat();
        Animal myAnimal = myCat;
        Animal.testClassMethod();
        myAnimal.testInstanceMethod();
    }
}

//The static method in Animal
//The instance method in Cat

Solution

  • From my perspective it seems like that both static methods in both the superclass and subclass are hidden, and by early-binding (compile-time binding) the appropriate method is chosen and the other one is hidden.

    For below, consider this code:

    class SuperClass {
        static void a() { System.out.println("SuperClass.a()"); }
        static void b() { System.out.println("SuperClass.b()"); }
        void testSuper() { // Call from "inside" SuperClass
            a(); // calls SuperClass.a()
            b(); // calls SuperClass.b()
        }
    }
    class SubClass extends SuperClass {
        static void b() { System.out.println("SubClass.b()"); }
        static void c() { System.out.println("SubClass.c()"); }
        void testSub() { // Call from "inside" SubClass
            a();   // calls SuperClass.a().
            b();   // calls SubClass.b().
            c();   // calls SubClass.c()
        }
    }
    class Test {
        void testSuper() { // Call SuperClass from "outside"
            SuperClass.a(); // calls SuperClass.a()
            SuperClass.b(); // calls SuperClass.b()
        }
        void testSub() { // Call SubClass from "outside"
            SubClass.a(); // calls SuperClass.a()
                          // IDE warning: The static method a() from the type SuperClass should be accessed directly
            SubClass.b(); // calls SubClass.b()
            SubClass.c(); // calls SubClass.c()
        }
    }
    

    There are two cases to consider:

    As you can see, only the b() in SuperClass is ever considered hidden. The b() in SubClass is never hidden.