Estou com uma dúvida em classes que extendem uma classe abstrata e implementam uma interface ao mesmo tempo.
Exemplo:
interface Data{
public void load();
}
abstract class Info{
public void load(){
/* faz alguma coisa*/
}
Se eu criar uma classe que extenda de Info e ao mesmo tempo implemente Data.
public class Empregado extends Info implements Data{
public void load(){
/* faz alguma coisa*/
}
}
Quando vou sobreescrever o método load.
Ele só aceita um método load().
Então este método load sobrescreve o método da interface e da classe abstract ao mesmo tempo.
procurei no livro da Kathy Sierra SCJP 5 (Estou estudando por ele) e não vi nada parecido.
O que acontece neste exemplo ?
Corrigi seu exemplo para o que você imaginava. De qualquer maneira, não há problemas em uma classe implementar um método abstrato e um método de uma interface.
interface Data {
public void load ();
}
abstract class Info{
abstract public void load ();
}
class Empregado extends Info implements Data {
public void load() {
System.out.println ("Empregado.load");
}
}
class TesteExtendsImplements {
public static void main(String[] args) {
Empregado e = new Empregado();
Data d = e;
Info i = e;
e.load(); // imprime "Empregado.load"
d.load(); // imprime "Empregado.load"
i.load(); // imprime "Empregado.load"
}
}
[quote=thingol]Corrigi seu exemplo para o que você imaginava. De qualquer maneira, não há problemas em uma classe implementar um método abstrato e um método de uma interface.
interface Data {
public void load ();
}
abstract class Info{
abstract public void load ();
}
class Empregado extends Info implements Data {
public void load() {
System.out.println ("Empregado.load");
}
}
class TesteExtendsImplements {
public static void main(String[] args) {
Empregado e = new Empregado();
Data d = e;
Info i = e;
e.load(); // imprime "Empregado.load"
d.load(); // imprime "Empregado.load"
i.load(); // imprime "Empregado.load"
}
}
[/quote]
É verdade, o método load (da classe Info ) precisa ser abstract pra ser obrigado a ser sobreescrito.
Neste caso então o método load (da classe Empregado) está satisfazendo a necessidade de de implementar o load da Interface Data e do método abstract da classe abstract Info.
É isto mesmo.
Se for isto aí ficou mais fácil de entender.
Obrigado pela ajuda.
Se você procurar na API do Java, vai ver que existem classes que fazem exatamente isso, oferecendo uma interface, que você pode implementar do zero, e uma classe-mãe de conveniência, que você pode estender para sobrescrever só os métodos que interessam no seu caso.
A única coisa que não funcionaria seria se você tivesse dois métodos load() com retornos diferentes (por exemplo, se sua classe abstrata retornasse File em vez de void). Aí você teria um erro de compilação.
[quote=rubinelli]Se você procurar na API do Java, vai ver que existem classes que fazem exatamente isso, oferecendo uma interface, que você pode implementar do zero, e uma classe-mãe de conveniência, que você pode estender para sobrescrever só os métodos que interessam no seu caso.
A única coisa que não funcionaria seria se você tivesse dois métodos load() com retornos diferentes (por exemplo, se sua classe abstrata retornasse File em vez de void). Aí você teria um erro de compilação.[/quote]
Só que no JDK a tal “classe de conveniência” implementa a tal interface. O que ele questiona é que a classe abstrata não está implementando explicitamente a interface. E é por isso que dá um pouco de confusão mesmo.
Uma forma de o Java se safar dessa confusão é que se algo tem várias formas de ser herdado (por exemplo, um método que tem a mesma assinatura em várias interfaces e classes abstratas, sendo que nenhuma delas estende explicitamente a outra), então, como tudo é abstrato mesmo, não há problemas e ele aceita direitinho. Haveria se houvesse algum código (ou seja, um método não abstrato, que devesse ser herdado).