Se um tipo implementa duas interfaces, e cada interfaceuma define um método que possui assinatura idêntica, na verdade, existe apenas um método e elas não são distinguíveis. Se, por exemplo, os dois métodos tiverem tipos de retorno conflitantes, será um erro de compilação. Essa é a regra geral de herança, substituição de método, ocultação e declaração, e se aplica também a possíveis conflitos não apenas entre 2 interfacemétodos herdados , mas também um método interfacee um super class, ou mesmo apenas conflitos devido ao apagamento de tipo de genéricos.
Exemplo de compatibilidade
Aqui está um exemplo em que você tem um interface Gift, que tem um present()método (como em apresentar presentes), e também um interface Guest, que também tem um present()método (como em, o convidado está presente e não está ausente).
Presentable johnnyé a Gifte a Guest.
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { void present(); }
interface Presentable extends Gift, Guest { }
public static void main(String[] args) {
Presentable johnny = new Presentable() {
@Override public void present() {
System.out.println("Heeeereee's Johnny!!!");
}
};
johnny.present(); // "Heeeereee's Johnny!!!"
((Gift) johnny).present(); // "Heeeereee's Johnny!!!"
((Guest) johnny).present(); // "Heeeereee's Johnny!!!"
Gift johnnyAsGift = (Gift) johnny;
johnnyAsGift.present(); // "Heeeereee's Johnny!!!"
Guest johnnyAsGuest = (Guest) johnny;
johnnyAsGuest.present(); // "Heeeereee's Johnny!!!"
}
}
O trecho acima compila e executa.
Observe que há apenas um @Override necessário !!! . Isso ocorre Gift.present()e Guest.present()é " @Override-equivalente" ( JLS 8.4.2 ).
Assim, johnny só tem uma implementação de present(), e não importa como você trata johnny, seja como Giftou como Guest, só há um método a ser chamado.
Exemplo de incompatibilidade
Aqui está um exemplo em que os dois métodos herdados NÃO são @Overrideequivalentes:
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { boolean present(); }
interface Presentable extends Gift, Guest { } // DOES NOT COMPILE!!!
// "types InterfaceTest.Guest and InterfaceTest.Gift are incompatible;
// both define present(), but with unrelated return types"
}
Isso reitera ainda que a herança de membros de um interfacedeve obedecer à regra geral das declarações de membros. Aqui temos Gifte Guestdefinimos present()com tipos de retorno incompatíveis: um voido outro boolean. Pelo mesmo motivo que você não pode um void present()e um boolean present()em um tipo, este exemplo resulta em um erro de compilação.
Resumo
Você pode herdar métodos que sejam @Overrideequivalentes, sujeitos aos requisitos usuais de substituição e ocultação de métodos. Como são @Override equivalentes, efetivamente existe apenas um método para implementar e, portanto, não há nada para distinguir / selecionar.
O compilador não precisa identificar qual método é para qual interface, porque uma vez que eles são considerados @Overrideequivalentes, eles são o mesmo método.
Resolver possíveis incompatibilidades pode ser uma tarefa complicada, mas isso é outra questão.
Referências