Now seeing above answers everyone knows that we can't override static methods, but one should not misunderstood about the concept of accessing static methods from subclass.
We can access static methods of super class with subclass reference if this static method has not been hidden by new static method defined in sub class.
For Example, see below code:-
public class StaticMethodsHiding {
public static void main(String[] args) {
SubClass.hello();
}
}
class SuperClass {
static void hello(){
System.out.println("SuperClass saying Hello");
}
}
class SubClass extends SuperClass {
// static void hello() {
// System.out.println("SubClass Hello");
// }
}
Output:-
SuperClass saying Hello
See Java oracle docs and search for What You Can Do in a Subclass for details about hiding of static methods in sub class.
The short answer is: it is entirely possible, but Java doesn't do it.
Here is some code which illustrates the current state of affairs in Java:
File Base.java:
package sp.trial;
public class Base {
static void printValue() {
System.out.println(" Called static Base method.");
}
void nonStatPrintValue() {
System.out.println(" Called non-static Base method.");
}
void nonLocalIndirectStatMethod() {
System.out.println(" Non-static calls overridden(?) static:");
System.out.print(" ");
this.printValue();
}
}
File Child.java:
package sp.trial;
public class Child extends Base {
static void printValue() {
System.out.println(" Called static Child method.");
}
void nonStatPrintValue() {
System.out.println(" Called non-static Child method.");
}
void localIndirectStatMethod() {
System.out.println(" Non-static calls own static:");
System.out.print(" ");
printValue();
}
public static void main(String[] args) {
System.out.println("Object: static type Base; runtime type Child:");
Base base = new Child();
base.printValue();
base.nonStatPrintValue();
System.out.println("Object: static type Child; runtime type Child:");
Child child = new Child();
child.printValue();
child.nonStatPrintValue();
System.out.println("Class: Child static call:");
Child.printValue();
System.out.println("Class: Base static call:");
Base.printValue();
System.out.println("Object: static/runtime type Child -- call static from non-static method of Child:");
child.localIndirectStatMethod();
System.out.println("Object: static/runtime type Child -- call static from non-static method of Base:");
child.nonLocalIndirectStatMethod();
}
}
If you run this (I did it on a Mac, from Eclipse, using Java 1.6) you get:
Object: static type Base; runtime type Child.
Called static Base method.
Called non-static Child method.
Object: static type Child; runtime type Child.
Called static Child method.
Called non-static Child method.
Class: Child static call.
Called static Child method.
Class: Base static call.
Called static Base method.
Object: static/runtime type Child -- call static from non-static method of Child.
Non-static calls own static.
Called static Child method.
Object: static/runtime type Child -- call static from non-static method of Base.
Non-static calls overridden(?) static.
Called static Base method.
Here, the only cases which might be a surprise (and which the question is about) appear to be the first case:
"The run-time type is not used to determine which static methods are called, even when called with an object instance (obj.staticMethod())."
and the last case:
"When calling a static method from within an object method of a class, the static method chosen is the one accessible from the class itself and not from the class defining the run-time type of the object."
Calling with an object instance
The static call is resolved at compile-time, whereas a non-static method call is resolved at run-time. Notice that although static methods are inherited (from parent) they are not overridden (by child). This could be a surprise if you expected otherwise.
Calling from within an object method
Object method calls are resolved using the run-time type, but static (class) method calls are resolved using the compile-time (declared) type.
Changing the rules
To change these rules, so that the last call in the example called Child.printValue(), static calls would have to be provided with a type at run-time, rather than the compiler resolving the call at compile-time with the declared class of the object (or context). Static calls could then use the (dynamic) type hierarchy to resolve the call, just as object method calls do today.
This would easily be doable (if we changed Java :-O), and is not at all unreasonable, however, it has some interesting considerations.
The main consideration is that we need to decide which static method calls should do this.
At the moment, Java has this "quirk" in the language whereby obj.staticMethod() calls are replaced by ObjectClass.staticMethod() calls (normally with a warning). [Note:ObjectClass is the compile-time type of obj.] These would be good candidates for overriding in this way, taking the run-time type of obj.
If we did it would make method bodies harder to read: static calls in a parent class could potentially be dynamically "re-routed". To avoid this we would have to call the static method with a class name -- and this makes the calls more obviously resolved with the compile-time type hierarchy (as now).
The other ways of invoking a static method are more tricky: this.staticMethod() should mean the same as obj.staticMethod(), taking the run-time type of this. However, this might cause some headaches with existing programs, which call (apparently local) static methods without decoration (which is arguably equivalent to this.method()).
So what about unadorned calls staticMethod()? I suggest they do the same as today, and use the local class context to decide what to do. Otherwise great confusion would ensue. Of course it means that method() would mean this.method() if method was a non-static method, and ThisClass.method() if method were a static method. This is another source of confusion.
Other considerations
If we changed this behaviour (and made static calls potentially dynamically non-local), we would probably want to revisit the meaning of final, private and protected as qualifiers on static methods of a class. We would then all have to get used to the fact that private static and public final methods are not overridden, and can therefore be safely resolved at compile-time, and are "safe" to read as local references.
Overriding depends on having an instance of a class. The point of polymorphism is that you can subclass a class and the objects implementing those subclasses will have different behaviors for the same methods defined in the superclass (and overridden in the subclasses). A static method is not associated with any instance of a class so the concept is not applicable.
There were two considerations driving Java's design that impacted this. One was a concern with performance: there had been a lot of criticism of Smalltalk about it being too slow (garbage collection and polymorphic calls being part of that) and Java's creators were determined to avoid that. Another was the decision that the target audience for Java was C++ developers. Making static methods work the way they do had the benefit of familiarity for C++ programmers and was also very fast, because there's no need to wait until runtime to figure out which method to call.
Actually we were wrong.
Despite Java doesn't allow you to override static methods by default, if you look thoroughly through documentation of Class and Method classes in Java, you can still find a way to emulate static methods overriding by following workaround:
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
class RegularEmployee {
private BigDecimal salary = BigDecimal.ONE;
public void setSalary(BigDecimal salary) {
this.salary = salary;
}
public static BigDecimal getBonusMultiplier() {
return new BigDecimal(".02");
}
public BigDecimal calculateBonus() {
return salary.multiply(this.getBonusMultiplier());
}
public BigDecimal calculateOverridenBonus() {
try {
// System.out.println(this.getClass().getDeclaredMethod(
// "getBonusMultiplier").toString());
try {
return salary.multiply((BigDecimal) this.getClass()
.getDeclaredMethod("getBonusMultiplier").invoke(this));
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
return null;
}
// ... presumably lots of other code ...
}
final class SpecialEmployee extends RegularEmployee {
public static BigDecimal getBonusMultiplier() {
return new BigDecimal(".03");
}
}
public class StaticTestCoolMain {
static public void main(String[] args) {
RegularEmployee Alan = new RegularEmployee();
System.out.println(Alan.calculateBonus());
System.out.println(Alan.calculateOverridenBonus());
SpecialEmployee Bob = new SpecialEmployee();
System.out.println(Bob.calculateBonus());
System.out.println(Bob.calculateOverridenBonus());
}
}
Resulting output:
0.02
0.02
0.02
0.03
what we were trying to achieve :)
Even if we declare third variable Carl as RegularEmployee and assign to it instance of SpecialEmployee, we will still have call of RegularEmployee method in first case and call of SpecialEmployee method in second case
RegularEmployee Carl = new SpecialEmployee();
System.out.println(Carl.calculateBonus());
System.out.println(Carl.calculateOverridenBonus());
A Static method, variable, block or nested class belongs to the entire class rather than an object.
A Method in Java is used to expose the behaviour of an Object / Class. Here, as the method is static (i.e, static method is used to represent the behaviour of a class only.) changing/ overriding the behaviour of entire class will violate the phenomenon of one of the fundamental pillar of Object oriented programming i.e, high cohesion. (remember a constructor is a special kind of method in Java.)
High Cohesion - One class should have only one role. For example: A car class should produce only car objects and not bike, trucks, planes etc. But the Car class may have some features(behaviour) that belongs to itself only.
Therefore, while designing the java programming language. The language designers thought to allow developers to keep some behaviours of a class to itself only by making a method static in nature.
The below piece code tries to override the static method, but will not encounter any compilation error.
public class Vehicle {
static int VIN;
public static int getVehileNumber() {
return VIN;
}}
class Car extends Vehicle {
static int carNumber;
public static int getVehileNumber() {
return carNumber;
}}
This is because, here we are not overriding a method but we are just re-declaring it. Java allows re-declaration of a method (static/non-static).
Removing the static keyword from getVehileNumber() method of Car class will result into compilation error, Since, we are trying to change the functionality of static method which belongs to Vehicle class only.
Also, If the getVehileNumber() is declared as final then the code will not compile, Since the final keyword restricts the programmer from re-declaring the method.
public static final int getVehileNumber() {
return VIN; }
Overall, this is upto software designers for where to use the static methods.
I personally prefer to use static methods to perform some actions without creating any instance of a class. Secondly, to hide the behaviour of a class from outside world.
Now seeing above answers everyone knows that we can't override static methods, but one should not misunderstood about the concept of accessing static methods from subclass.
For Example, see below code:-
Output:-
Thanks
The short answer is: it is entirely possible, but Java doesn't do it.
Here is some code which illustrates the current state of affairs in Java:
File
Base.java
:File
Child.java
:If you run this (I did it on a Mac, from Eclipse, using Java 1.6) you get:
Here, the only cases which might be a surprise (and which the question is about) appear to be the first case:
"The run-time type is not used to determine which static methods are called, even when called with an object instance (
obj.staticMethod()
)."and the last case:
"When calling a static method from within an object method of a class, the static method chosen is the one accessible from the class itself and not from the class defining the run-time type of the object."
Calling with an object instance
The static call is resolved at compile-time, whereas a non-static method call is resolved at run-time. Notice that although static methods are inherited (from parent) they are not overridden (by child). This could be a surprise if you expected otherwise.
Calling from within an object method
Object method calls are resolved using the run-time type, but static (class) method calls are resolved using the compile-time (declared) type.
Changing the rules
To change these rules, so that the last call in the example called
Child.printValue()
, static calls would have to be provided with a type at run-time, rather than the compiler resolving the call at compile-time with the declared class of the object (or context). Static calls could then use the (dynamic) type hierarchy to resolve the call, just as object method calls do today.This would easily be doable (if we changed Java :-O), and is not at all unreasonable, however, it has some interesting considerations.
The main consideration is that we need to decide which static method calls should do this.
At the moment, Java has this "quirk" in the language whereby
obj.staticMethod()
calls are replaced byObjectClass.staticMethod()
calls (normally with a warning). [Note:ObjectClass
is the compile-time type ofobj
.] These would be good candidates for overriding in this way, taking the run-time type ofobj
.If we did it would make method bodies harder to read: static calls in a parent class could potentially be dynamically "re-routed". To avoid this we would have to call the static method with a class name -- and this makes the calls more obviously resolved with the compile-time type hierarchy (as now).
The other ways of invoking a static method are more tricky:
this.staticMethod()
should mean the same asobj.staticMethod()
, taking the run-time type ofthis
. However, this might cause some headaches with existing programs, which call (apparently local) static methods without decoration (which is arguably equivalent tothis.method()
).So what about unadorned calls
staticMethod()
? I suggest they do the same as today, and use the local class context to decide what to do. Otherwise great confusion would ensue. Of course it means thatmethod()
would meanthis.method()
ifmethod
was a non-static method, andThisClass.method()
ifmethod
were a static method. This is another source of confusion.Other considerations
If we changed this behaviour (and made static calls potentially dynamically non-local), we would probably want to revisit the meaning of
final
,private
andprotected
as qualifiers onstatic
methods of a class. We would then all have to get used to the fact thatprivate static
andpublic final
methods are not overridden, and can therefore be safely resolved at compile-time, and are "safe" to read as local references.The following code shows that it is possible:
Overriding depends on having an instance of a class. The point of polymorphism is that you can subclass a class and the objects implementing those subclasses will have different behaviors for the same methods defined in the superclass (and overridden in the subclasses). A static method is not associated with any instance of a class so the concept is not applicable.
There were two considerations driving Java's design that impacted this. One was a concern with performance: there had been a lot of criticism of Smalltalk about it being too slow (garbage collection and polymorphic calls being part of that) and Java's creators were determined to avoid that. Another was the decision that the target audience for Java was C++ developers. Making static methods work the way they do had the benefit of familiarity for C++ programmers and was also very fast, because there's no need to wait until runtime to figure out which method to call.
Actually we were wrong.
Despite Java doesn't allow you to override static methods by default, if you look thoroughly through documentation of Class and Method classes in Java, you can still find a way to emulate static methods overriding by following workaround:
Resulting output:
what we were trying to achieve :)
Even if we declare third variable Carl as RegularEmployee and assign to it instance of SpecialEmployee, we will still have call of RegularEmployee method in first case and call of SpecialEmployee method in second case
just look at output console:
;)
A Static method, variable, block or nested class belongs to the entire class rather than an object.
A Method in Java is used to expose the behaviour of an Object / Class. Here, as the method is static (i.e, static method is used to represent the behaviour of a class only.) changing/ overriding the behaviour of entire class will violate the phenomenon of one of the fundamental pillar of Object oriented programming i.e, high cohesion. (remember a constructor is a special kind of method in Java.)
High Cohesion - One class should have only one role. For example: A car class should produce only car objects and not bike, trucks, planes etc. But the Car class may have some features(behaviour) that belongs to itself only.
Therefore, while designing the java programming language. The language designers thought to allow developers to keep some behaviours of a class to itself only by making a method static in nature.
The below piece code tries to override the static method, but will not encounter any compilation error.
This is because, here we are not overriding a method but we are just re-declaring it. Java allows re-declaration of a method (static/non-static).
Removing the static keyword from getVehileNumber() method of Car class will result into compilation error, Since, we are trying to change the functionality of static method which belongs to Vehicle class only.
Also, If the getVehileNumber() is declared as final then the code will not compile, Since the final keyword restricts the programmer from re-declaring the method.
Overall, this is upto software designers for where to use the static methods. I personally prefer to use static methods to perform some actions without creating any instance of a class. Secondly, to hide the behaviour of a class from outside world.