Uma coisa curiosa acontece em Java quando você usa uma classe abstrata para implementar uma interface: alguns dos métodos da interface podem estar completamente ausentes (ou seja, não existe uma declaração abstrata ou uma implementação real), mas o compilador não reclama.
Por exemplo, dada a interface:
public interface IAnything {
void m1();
void m2();
void m3();
}
a seguinte classe abstrata é alegremente compilada sem aviso ou erro:
public abstract class AbstractThing implements IAnything {
public void m1() {}
public void m3() {}
}
Você pode explicar o porquê?
java
interface
abstract-class
Giulio Piancastelli
fonte
fonte
:w
um dos arquivos.Respostas:
Isso ocorre porque, se uma classe é abstrata, por definição você é obrigado a criar subclasses para instanciar. As subclasses serão necessárias (pelo compilador) para implementar quaisquer métodos de interface que a classe abstrata tenha deixado de fora.
Seguindo o código de exemplo, tente criar uma subclasse
AbstractThing
sem implementar om2
método e veja quais erros o compilador fornece. Isso forçará você a implementar esse método.fonte
Perfeitamente bem.
Você não pode instanciar classes abstratas .. mas as classes abstratas podem ser usadas para hospedar implementações comuns para m1 () e m3 ().
Portanto, se a implementação de m2 () for diferente para cada implementação, mas m1 e m3 não. Você pode criar diferentes implementações concretas de IAnything apenas com a implementação de m2 diferente e derivar do AbstractThing - honrando o princípio DRY. Validar se a interface está completamente implementada para uma classe abstrata é inútil.
Atualização : Curiosamente, acho que o C # impõe isso como um erro de compilação. Você é forçado a copiar as assinaturas do método e prefixá-las com 'abstract public' na classe base abstrata neste cenário. (Algo novo todos os dias :)
fonte
Isso é bom. Para entender o que foi dito acima, primeiro é necessário entender a natureza das classes abstratas. Eles são semelhantes às interfaces a esse respeito. É o que a Oracle diz sobre isso aqui .
Então você tem que pensar no que acontece quando uma interface estende outra interface. Por exemplo ...
... como você pode ver, isso também compila perfeitamente. Simplesmente porque, assim como uma classe abstrata, uma interface NÃO pode ser instanciada. Portanto, não é necessário mencionar explicitamente os métodos do seu "pai". No entanto, TODAS as assinaturas do método pai tornam-se implicitamente parte da interface de extensão ou implementação da classe abstrata. Portanto, uma vez que uma classe apropriada (uma que possa ser instanciada) estenda o descrito acima, será necessário garantir que todos os métodos abstratos sejam implementados.
Espero que ajude ... e Allahu 'alam!
fonte
Interface significa uma classe que não possui implementação de seu método, mas apenas com declaração.
Por outro lado, a classe abstrata é uma classe que pode ter implementação de algum método, juntamente com algum método com apenas declaração, sem implementação.
Quando implementamos uma interface para uma classe abstrata, isso significa que a classe abstrata herdou todos os métodos da interface. Como não é importante implementar todo o método na classe abstrata, no entanto, trata-se da classe abstrata (também por herança), portanto a classe abstrata pode deixar parte do método na interface sem implementação aqui. Porém, quando essa classe abstrata será herdada por alguma classe concreta, eles deverão implementar todos os métodos não implementados na classe abstrata.
fonte
Dada a interface:
É assim que o Java realmente o vê:
Portanto, você pode deixar alguns (ou todos) esses
abstract
métodos não implementados, exatamente como faria no caso deabstract
classes estendendo outraabstract
classe.Quando
implement
uminterface
, a regra de que todos osinterface
métodos devem ser implementados na derivadaclass
, aplica-se apenas ao concretoclass
de execução (ou seja, que não éabstract
em si).Se você realmente planeja criar uma
abstract class
saída, não há uma regra que diga a vocêimplement
todos osinterface
métodos (observe que, nesse caso, é obrigatório declarar a derivadaclass
comoabstract
)fonte
javap IAnything.class
para gerar o segundo trecho de código.Referência: http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
fonte
Classes abstratas não são necessárias para implementar os métodos. Portanto, mesmo que implemente uma interface, os métodos abstratos da interface podem permanecer abstratos. Se você tentar implementar uma interface em uma classe concreta (por exemplo, não abstrata) e não implementar os métodos abstratos, o compilador lhe dirá: Implemente os métodos abstratos ou declare a classe como abstrata.
fonte