greenHorn
greenHorn

Reputation: 557

What is significance of the term " hiding " in the method hiding concept in java?

The question has been put up to discuss around the term hiding which is associated with static methods in java. Whenever a static method with the same signature is defined in the parent and the child class, the child class method is said to have hidden the method in the parent class. My question is around the usage of hiding, as we know static methods would be accessed by the class name or if we try to create a reference (which is a bad practice), method would be called based on the reference type. So how does hiding comes into picture, take example of below code:

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

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

    public static void main(String[] args) {
        Cat myCat = new Cat();
        Animal myAnimal = myCat;
        Animal.testClassMethod(); // prints The static method in Animal
    }
}

Can someone please explain how child method has hidden the parent method here? (parent method is being called using parent reference, so how does hiding comes into picture)

Upvotes: 2

Views: 318

Answers (4)

Andrew
Andrew

Reputation: 49656

How has the child method hidden the parent method here?

As you said, by defining a static method with the identical signature.

How does hiding comes into the picture?

Cat.testClassMethod();

Some may expect the invocation of the parent method here (by analogy with polymorphism). But the idea of hiding by class methods is different:

If a class C declares or inherits a static method m, then m is said to hide any method m', where the signature of m is a subsignature (§8.4.2) of the signature of m', in the superclasses and superinterfaces of C that would otherwise be accessible (§6.6) to code in C.
...
A hidden method can be accessed by using a qualified name or by using a method invocation expression (§15.12) that contains the keyword super or a cast to a superclass type.
...

class Super {
    static String greeting() { return "Goodnight"; }
    String name() { return "Richard"; }
}
class Sub extends Super {
    static String greeting() { return "Hello"; }
    String name() { return "Dick"; }
}
class Test {
    public static void main(String[] args) {
        Super s = new Sub();
        System.out.println(s.greeting() + ", " + s.name());  // Goodnight, Dick
    }
}

JLS 10 - 8.4.8.2. Hiding (by Class Methods)

This example is perfect to show the difference between overriding and hiding. At the same time, it is a bad practice demonstration - calling static methods on an instance.

I will try to make it clear by providing another example.

Since public static methods are inherited, the following snippet

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

class Cat extends Animal {
    public static void main(String[] args) {
        // Cat: I don't have own method, probably I inherited it from the parent.
        //      O, yes. I can call it. 
        Cat.testClassMethod();
    }
}

prints

The static method in Animal

Now we're going to add testClassMethod to Cat.

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

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

    public static void main(String[] args) {
        // Cat: I have two version of the method: mine and the inherited one.
        //      The caller specified my class name, so he wanted my version. 
        //      I will call my method hiding the parent method.
        Cat.testClassMethod();

        // If he wanted Animal's version, he would write
        Animal.testClassMethod();

        // or (DON'T DO THIS)
        ((Animal)new Cat()).testClassMethod();
    }
}

Upvotes: 1

user4602302
user4602302

Reputation:

static methods don't take part in dynamic binding (polymorphism).

static methods aren't overritten, static methods are hidden by the subclass.

someone who calls Cat.testClassMethod() might expect the behaviour of Animal.testClassMethod()

So Cat.testClassMethod() is hiding Animal.testClassMethod()

Upvotes: 0

ernest_k
ernest_k

Reputation: 45339

This demonstrates exactly why it's a bad practice to intend to hide a static method. The method is chosen statically, at compile time, without any consideration for the actual instance type.

I suppose the take home phrase should be "hiding is not overriding... and don't do it", to mean that Java doesn't even look at the object/instance (only looking at the declared type):

Cat myCat = new Cat();
Animal myAnimal = myCat;
Animal.testClassMethod();
myAnimal.testClassMethod(); //bad to do, but you can see it uses the declared "Animal" class

Cat.testClassMethod(); //Uses method in Cat
myCat.testClassMethod(); //Uses method in Cat

((Animal) null).testClassMethod(); //Uses Animal method, doesn't look at instance
((Cat) null).testClassMethod(); //Uses Cat method, doesn't look at instance

Now the interesting part: what if you remove the method from Cat? All of these invocations will still work, using the Animal method, which means that:

  • It's a very bad practice to hide static methods
  • It's equally bad to use class instances to invoke static methods, because in the case of hidden methods, it's easy to be misled...

To answer the question: hiding is illustrated with Cat.testClassMethod() or myCat.testClassMethod(), which invokes the static method based on the declared type. When there's no testClassMethod() in Cat, Java calls the parent's.

Upvotes: 1

aarnaut
aarnaut

Reputation: 557

All final, static and private methods and variables use static binding and are bonded by compiler. Static binding uses Type information for binding (in this case Animal).

So, in your case myAnimal.testClassMethod(); will print the static method in Animal because declared type is Animal.

Upvotes: 0

Related Questions