В текущем состоянии вашей программы, если бы вы переопределили A#foo
в C.java
(где метод по умолчанию возвращает true
, а переопределенный метод возвращает false
, печать C#foo
привела бы к false
, полностью игнорируя метод по умолчанию.
Любые абстрактные методы, определенные в абстрактном классе, должны быть переопределены первым конкретным классом, который расширяет абстрактный класс. По этой причине требуется, чтобы C.java
переопределяло A#foo
.
Методы по умолчанию в интерфейсах не требуется переопределять.
Однако оба метода имеют одинаковые сигнатуры, а это означает, что один из них необходимо переопределить, а другой может переопределить.
Это чрезвычайно плохой дизайн, и его не следует использовать, поскольку методы с одинаковой сигнатурой не могут быть переопределены одновременно. Если вы хотите, чтобы вам требовалось переопределить абстрактный метод, просто измените имя абстрактного метода или метода по умолчанию на что-то другое, кроме 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() {
...
}
}
Если вы хотите переопределить только A#foo
в некоторых случаях, вы можете просто полностью удалить абстрактный метод и сохранить метод по умолчанию в B.java
и переопределить его в C.java
:
abstract class A {
}
interface B {
default boolean foo() { return doBlah(); }
}
class C extends A implements B {
@Override
public boolean foo() {
...
}
}
Если удаление A#foo
невозможно, переименуйте метод по умолчанию, B#foo
, во что-то другое.
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() {
...
}
}
person
Jacob G.
schedule
12.05.2017
A
не реализует интерфейсB
? Тогда классуC
нужно просто расширить классA
, чтобы воспользоваться преимуществами обоих супертипов. - person Bobulous   schedule 13.05.2017