At your program's current state, if you were to override A#foo
in C.java
(where the default method returns true
and the overridden method returns false
, printing C#foo
would result in false
, completely ignoring the default method.
Any abstract methods defined in an abstract class are required to be overridden by the first concrete class that extends the abstract class. For this reason, it is required that C.java
overrides A#foo
.
Default methods within interfaces are not required to be overridden.
However, both methods share identical signatures, meaning that one is required to be overridden and the other may be overridden.
This is extremely poor design and should not be used, as methods that share an identical signature cannot both be overridden. If you want to be required to override the abstract method, then simply change the name of either the abstract method, or the default method to something other than foo
.
abstract class A {
abstract boolean bar();
}
interface B {
default boolean foo() { return doBlah(); }
}
class C extends A implements B {
@Override
public boolean foo() {
...
}
@Override
public boolean bar() {
...
}
}
If you're looking to only override A#foo
in some cases, then you can simply remove the abstract method entirely and retain the default method within B.java
, and override it in C.java
:
abstract class A {
}
interface B {
default boolean foo() { return doBlah(); }
}
class C extends A implements B {
@Override
public boolean foo() {
...
}
}
If removing A#foo
is not an option, then rename the default method, B#foo
, to something else.
abstract class A {
abstract boolean foo();
}
interface B {
default boolean bar() { return doBlah(); }
}
class C extends A implements B {
@Override
public boolean foo() {
...
}
@Override
public boolean bar() {
...
}
}