They can't really.
If you do this:
class A
{
static void f() { System.out.printf("A.f()\n"); }
}
class B extends A
{
static void f() { System.out.printf("B.f()\n"); }
}
{
A a = new B();
a.f();
}
Which f do you think gets called? It's A.f() not B.f(). Static methods
don't hide, or override, each other like instance methods. Polymorphism
doesn't work with Static methods in any real sense.
It's an odd quirk that Java even lets you access the static methods using
an instance object like the a variable above instead of limiting you to
just use them as A.f(). But when you do use an instance variable like a,
the method called has nothing to do with the run time value of the
variable. You can do this for example and it works just fine:
{
A a = null;
a.f();
}
You don't get a null pointer exception because the compiler is not using
the variable "a" at run time for this call. It's just a hard-coded call to
A.f() which the compiler lets you syntactically specify as a.f(); It just
uses the defined type of the a variable to figure out what method to call.
I have no clue why the designers of Java even allowed that because it is
confusing - it makes people think it might work like instance variables
where the type of the object at run time is going to control what method
gets called when it doesn't.
Imagine that abstract static methods were possible, or even
just that static methods were overridable. What output would
you expect from
abstract class Super {
abstract static void method(); // just pretend ...
}
class Main {
public static void main(String[] unused) {
Super.method(); // what happens here?
Compile error - Super.method is abstract.
There's no reason the compiler couldn't allow abstract static methods.
They would produce a compile error if the method resolved to the abstract
version at compile time, and like normal abstract methods, it would force
all non abstract subclasses to implement them.
It just makes no sense to do so and would extend the confusion of thinking
that they created some form of static polymorphism when they didn't.
That reason you would want to use real abstract methods is so you could
code to the superclass, and use standard polymorphism to substitute
different subclass objects at run time. But, from the above examples, think
about what happens when you do that with static methods.
If you try to code to the superclass:
method(SuperClass s)
{
s.staticMethodCall();
}
And then try to substitute a subclass object at run time:
method(new SubClass())
What method gets called? The SuperClass method is called no matter
what object you pass to method() so it makes no sense to try
and code to an Abstract SuperClass since there is no polymorphism of
static methods. The call to the abstract static methods would
always produce a compile error.