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
Hibernate - Foreign Keys Instead of Entities
Whats the Best Way to Recursively Reverse a String in Java
Import Sun.Misc.Base64Encoder Results in Error Compiled in Eclipse
Constructor Synchronization in Java
Java 8 Lambda Expression and First-Class Values
Java Enum Methods - Return Opposite Direction Enum
Hibernate Table Not Mapped Error in Hql Query
How to Deserialize a Blank JSON String Value to Null for Java.Lang.String
Java Static Initialization Order
How to Read an Aws S3 File with Java
Using a Prepared Statement and Variable Bind Order by in Java with Jdbc Driver
Converting Date-String to a Different Format
How Does Java Garbage Collector Handle Self-Reference
How to Invalidate an User Session When He Logs Twice with the Same Credentials