Why Are Class Static Methods Inherited But Not Interface Static Methods

Why are class static methods inherited but not interface static methods?

Here's my guess.

Since Cat can only extend one class if Cat extends Animal then Cat.identify has only one meaning. Cat can implement multiple interfaces each of which can have a static implementation. Therefore, the compiler would not know which one to choose?

However, as pointed out by the author,

Java already has this problem, with default methods. If two interfaces
declare default void identify(), which one is used? It's a compile
error, and you have to implement an overriding method (which could
just be Animal.super.identify()). So Java already resolves this
problem for default methods – why not for static methods?

If I was to guess again, I'd say that with default the implementation is part of Cat's vtable. With static it cannot be. The main function must bind to something. At compile time Cat.identify could be replaced with Animal.identify by the compiler but the code wouldn't match reality if Cat was recompiled but not the class that contains main.

In java 8, why cannot call the interface static method that the current class is implementing

Addition of static methods in interface in Java 8 came with 1 restriction - those methods cannot be inherited by the class implementing it. And that makes sense, as a class can implement multiple interface. And if 2 interfaces have same static method, they both would be inherited, and compiler wouldn't know which one to invoke.

However, with extending class, that's no issue. static class methods are inherited by subclass.

See JLS §8.4.8:

A class C inherits from its direct superclass all concrete methods m (both static and instance) of the superclass

...

A class C inherits from its direct superclass and direct superinterfaces all abstract and default (§9.4) methods m

...

A class does not inherit static methods from its superinterfaces.

Are static methods inherited in Java?

All methods that are accessible are inherited by subclasses.

From the Sun Java Tutorials:

A subclass inherits all of the public and protected members of its parent, no matter what package the subclass is in. If the subclass is in the same package as its parent, it also inherits the package-private members of the parent. You can use the inherited members as is, replace them, hide them, or supplement them with new members

The only difference with inherited static (class) methods and inherited non-static (instance) methods is that when you write a new static method with the same signature, the old static method is just hidden, not overridden.

From the page on the difference between overriding and hiding.

The distinction between hiding and overriding has important implications. The version of the overridden method that gets invoked is the one in the subclass. The version of the hidden method that gets invoked depends on whether it is invoked from the superclass or the subclass

Why interface methods can't be static in class that implements the interface?

One could say: because @Override and static simply do not go together.

Keep in mind: polymorphism only works for non-static methods. static means that your method is "attached" to the containing class.

In other words: you know everything about static method invocations at compile time. But the process of determining which overridden method to invoke happens at runtime. These two concepts do not go together in Java.

Why can't I use from the static method of the implemented interface?

From the Java Language Specification,

A class C inherits from its direct superclass all concrete methods m
(both static and instance) of the superclass for which all of the
following are true:

  • [...]

A class C inherits from its direct superclass and direct
superinterfaces all abstract and default (§9.4) methods m for which
all of the following are true:

  • [...]

A class does not inherit static methods from its superinterfaces.

So that method is not inherited.

You can statically import the member

import static com.example.Interface1.printName;
...
printName();

or use it with the fully qualified type name

com.example.Interface1.printName();

or import the type to which printName belongs and invoke it with its short name

import static com.example.Interface1;
...
Interface1.printName();


Related Topics



Leave a reply



Submit