В следующих двух интерфейсах methodA()
идентично определяется в терминах параметров (нет) и типа возвращаемого значения (int). Класс реализации внизу определяет единственный метод с этой точной сигнатурой. Поскольку он соответствует обоим интерфейсам, у вас не возникает проблем - любые вызовы, сделанные через ссылку типа InterfaceA или InterfaceB, будут отправлены этой реализации.
Второй methodB()
определяется как возвращающий любой подтип Number
(или Number
) в InterfaceA
. InterfaceB
определяет methodB()
как возвращающий Integer
, который является подтипом Number
. Класс реализации фактически реализует метод с Integer
, что соответствует контракту как InterfaceA
, так и InterfaceB
. Здесь тоже нет проблем.
Закомментированный случай реализации methodB()
как возврата Double
, однако, не будет работать: хотя он будет удовлетворять контракту InterfaceA
, он будет конфликтовать с InterfaceB
(что требует Integer
).
Если бы InterfaceA
и InterfaceB
также указывали (разные) контракты для methodC()
(закомментировано в примере), это было бы противоречиво и создавало бы ошибку компилятора. Реализация обеих подписей (различающихся только типом возврата) не разрешена в Java.
Приведенные выше правила также будут выполняться, если добавить методы к методам. Для простоты я исключил это из примера.
public interface InterfaceA {
public int methodA();
public Number methodB();
// public int methodC(); // conflicting return type
}
public interface InterfaceB {
public int methodA();
public Integer methodB();
// public String methodC(); // conflicting return type
}
public class ImplementationOfAandB implements InterfaceA, InterfaceB {
public int methodA() {
return 0;
}
public Integer methodB() {
return null;
}
// This would NOT work:
// public Double methodB() {
// return null;
// }
}