public class Test
{
static int i = 1;
static void m1()
{
}
}
class Test1 extends Test
{
int i = 1; //allowed
void m1() // not allowed; Both are instance level, so why this difference? Both can be accessed with super keyword
{
}
}
Why can't the static method be hidden with the same signature, but the static field is allowed to do this? Both are instance level, so why is only the static field allowed?
Method hiding can be defined as, "if a subclass defines a static method with the same signature as a static method in the super class, in such a case, the method in the subclass hides the one in the superclass." The mechanism is known as method hiding. It happens because static methods are resolved at compile time.
In method overriding, when base class reference variable pointing to the object of the derived class, then it will call the overridden method in the derived class. In the method hiding, when base class reference variable pointing to the object of the derived class, then it will call the hidden method in the base class.
In method hiding, you can hide the implementation of the methods of a base class from the derived class using the new keyword. Or in other words, in method hiding, you can redefine the method of the base class in the derived class by using the new keyword.
When super class and sub class contains same method including parameters and if they are static. The method in the super class will be hidden by the one that is in the sub class. This mechanism is known as method hiding.
m1()
in class Test
is a static
method, while m1()
in Test1
is non static. Now imagine if this would have been allowed then which implementation would be picked by runtime when you execute below statement:
new Test1().m1();
Since instance of child class (Test1
in your case) can access also access static method from parent class (from Test
). That is why it is not allowed.
For you next question why variable with same name is allowed in Test1
: parent class' static variable can not be accessed from child class instance. In other words parent class' static state is hidden from child. That is
Test1.i; // compilation error, can't access parent's static variable
will result in compilation error. And if you try
new Test1().i; // will access Test1's i variable
it will point to the child class' state not parent's. That is why child class can have variable with the same name.
Note: If i
in Test
was non-static, even in that case Test1 can have variable with name i
. In this case i
in Test1
will shadow i
in Test
.
EDIT
From Shahaan Syed's comment:
new Test1().i;
why is this allowed is my concerned
To put Shahaan Syed's confusion in another words: Why
As Kevin Esche commented, I also think that Java messed up somewhere by allowing access to static
methods of parent class from instance of child class. Though it is not a good practice and compiler generates warning as well.
Here's a quote from (JLS §8.3):
In this respect, hiding of fields differs from hiding of methods (§8.4.8.3), for there is no distinction drawn between static and non-static fields in field hiding whereas a distinction is drawn between static and non-static methods in method hiding.
But I could not find any reasoning behind this in JLS.
I think instead of generating warning there should have been compile time error. That is accessing both static
field and static
method of parent class from child class instance, should have been compiler error. In this respect things would have been consistent and easy to understand. But again it's just my thought.
Another interesting question on the same line: Why isn't calling a static method by way of an instance an error for the Java compiler?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With