Consider the following case,
interface IFace1 {
default void printHello() {
System.out.println("IFace1");
}
}
interface IFace2 {
void printHello();
}
public class Test implements IFace1, IFace2 {
public static void main(String[] args) {
Test test = new Test();
test.printHello();
IFace1 iface1 = new Test();
iface1.printHello();
IFace2 iface2 = new Test();
iface2.printHello();
}
@Override
public void printHello() {
System.out.println("Test");
}
}
In above example I am getting following output which is quite expected.
Test
Test
Test
I have been reading about Java-8
default methods and specifically about Extending Interfaces That Contain Default Methods
2nd bullet : Redeclare the default method, which makes it abstract.
In above example where I have two interfaces which have default method with same name and when I implemented both I was only able to reach to the implementation of printHello
of Test
which refers to IFace2
.
I have few questions about this,
printHello
method of IFace1
and if I can't than why ? IFace1
which is may be now shadowed by other method ?Quote says, you can make the default
method abstract
in it's child interface. For example,
interface IFace2 extends IFace1 {
void printHello();
}
Here when I implement IFace2
I won't be actually able to reach default
method of IFace1
that is exactly what is happening in my case.
When superclass and subclass contain the same method including parameters and if they are static. The method in the superclass will be hidden by the one that is in the subclass. This mechanism is known as method shadowing.
Shadowing is a computer programming phenomenon in which a variable declared in one scope (like decision block, method, or inner class) has the same name as another declaration of the enclosing scope. In this case, the declaration shadows the declaration of the enclosing scope. ADVERTISEMENT.
It seems that you are a bit confused by the presence of a default
method. So let’s forget for a moment that IFace1.printHello()
is a default
method. So then, there is a clear situation: Test
implements two interfaces, IFace1
and IFace2
, which happen to have a method with the same name and signature.
Test
implements that method and therefore implements the method for both interfaces. The new feature of default
methods does not change anything about this logic. Moreover, the language designers took care that adding a default
method does not affect the behavior of existing code, so if your class implements the method, the presence of default
methods becomes irrelevant.
However, if you write code that is aware of the presence of default
methods, you may invoke it, if it is declared or inherited by a direct super interface, i.e. in your code you may use IFace1.super.printHello()
to invoke the default
method of IFace1
.
The rules are not much different to the rules of super classes. If you change the interfaces so that interface IFace2
extends IFace1
and still declares printHello()
as an abstract
method, then this abstract
method does override the default
method and you can’t invoke IFace1.super.printHello()
from within Test
anymore.
As said, these rules are not much different to ordinary instance methods. If Test
declares a method printHello()
, that’s the only method that you can invoke by a reference to a Test
instance, regardless whether its declared type is Test
, IFace1
or IFace2
. Only implementation methods of Test
itself may do super
invocations.
The main difference comes into play when the possible multiple inheritance of interfaces is involved. If your class Test
does not implement the method printHello()
, it depends on the inheritance relationship of the two interfaces, what will happen
IFace2
extends IFace1
, it’s abstract method redeclares the default
method, hence a compiler error occurs, as Test
must implement the abstract
methodIFace2
does not extend IFace1
, there are ambiguously two inheritable methods with the same name and signature, therefore Test
will not inherit the default
method, and a compiler error occurs, as Test
must implement the abstract
methodIFace1
extends IFace2
, Test
will inherit the default
method. It will also inherit it if Test
does not implement IFace2
, but this should come at a surprise…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