-->

Why is it called “method hiding”?

2019-06-22 08:02发布

问题:

From the docs, "If a subclass defines a static method with the same signature as a static method in the superclass, then the method in the subclass hides the one in the superclass."

I understand the difference between method hiding and overriding. However, it's strange to say that the subclass hides the superclass method because if you have the following:

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 superclass's static method is called. But by the definition of hiding, the method in the subclass is hiding the one in the superclass. I don't see how the subclass is "covering up/hiding" the superclass static method, as the superclass's method is the one that's actually called.

回答1:

The superclass's static method is called.

Yes. But that is because you explicitly named the superclass's static method by qualifying with the superclass name in the call statement.

If you had written the main like this instead:

public static void main(String[] args) {
    ...
    testClassMethod();
}

then you would have seen that the Cat version of testClassMethod was called. Here, the Cat.testClassMethod method hides the Animal.testClassMethod method



回答2:

Cat's testClassMethod() hides Animal.testClassMethod(), since if you didn't have a static testClassMethod() in the Cat class, Cat.testClassMethod() would invoke Animal.testClassMethod().

When you call Animal.testClassMethod(), it's can't be hidden by a sub-class's method.



回答3:

I think it's called "hiding" because you can no longer access the superclass's method simply by writing the method name. Without the public static void testClassMethod() definition in Cat, your main could say

testClassMethod();

to call the method defined in Animal. But you can no longer do that. Yes, you can still call it by giving it the qualified name:

Animal.testClassMethod();

so it's not completely hidden. But please note that people who write language standards have to come up with names for some concepts that may not quite match the meanings we give words in the non-computing world, so sometimes coming close is the best they can do. You can't try to take the terminology literally. The term hidden has a formal definition somewhere in the JLS, I believe; and that means when you see the term used in the JLS, it means whatever the JLS defines it to mean, neither more nor less.



回答4:

Consider adding this to your posted example

class Dog extends Animal {
    // nothing here
}

Now if you do this:

new Cat().testClassMethod();
new Dog().testClassMethod();

each of the above will give different output. So you could say that the static method in Cat did hide the Animal's static method - while there's no such thing as overriding for static methods, one of the animals printed according to Animal's code and the other did not.

(P.S. I'm definitely not encouraging you to call static methods in this way.)