Numa das minhas entrevistas, foi-me pedido que explicasse a diferença entre uma Interface e uma **Aula de abstracto***.
Aqui'é a minha resposta:
Os métodos de uma interface Java são implicitamente abstractos e não pode ter implementações. Uma classe abstrata Java pode ter métodos de instância que implementam um comportamento padrão.
Variáveis declaradas em uma interface Java são, por padrão, finais. Um A classe abstrata pode conter variáveis não-final.
os membros de uma interface Java são públicos por padrão. Um resumo Java A aula pode ter os sabores habituais dos membros da classe como privado, protegidos, etc.
Uma interface Java deve ser implementada usando a palavra-chave "implementos"; A A classe abstrata Java deve ser estendida usando a palavra-chave "extends".
Uma interface pode estender apenas outra interface Java, uma classe abstrata pode estender outra classe Java e implementar múltiplas interfaces Java.
Uma classe Java pode implementar múltiplas interfaces, mas pode estender-se apenas uma classe abstrata.
Entretanto, o entrevistador não ficou satisfeito e me disse que esta descrição representava "conhecimento de livros".
Ele me pediu uma resposta mais prática, explicando quando eu escolheria uma aula abstrata em vez de uma interface, usando exemplos práticos.
Onde é que eu errei?
Nada é perfeito neste mundo. Eles podiam estar à espera de uma abordagem mais prática.
Mas depois da sua explicação você poderia acrescentar estas linhas com uma abordagem ligeiramente diferente.
Interfaces são regras (regras porque você deve dar uma implementação a elas que você pode't ignorar ou evitar, para que elas sejam impostas como regras) que funciona como um documento de entendimento comum entre várias equipes no desenvolvimento de software.
As interfaces dão a idéia do que deve ser feito, mas não como será feito. Portanto, a implementação depende completamente do desenvolvedor, seguindo as regras dadas (meios dados a assinatura dos métodos).
As classes abstractas podem conter declarações abstractas, implementações concretas, ou ambas.
Declarações abstratas são como regras a serem seguidas e implementações concretas são como diretrizes (você pode usá-las como estão ou pode ignorá-las anulando e dando sua própria implementação a elas).
Além disso, que métodos com a mesma assinatura podem alterar o comportamento em diferentes contextos são fornecidos como declarações de interface como regras a implementar em conformidade em diferentes contextos.
Edit: Java 8 facilita a definição de métodos padrão e estáticos na interface.
public interface SomeInterfaceOne {
void usualAbstractMethod(String inputString);
default void defaultMethod(String inputString){
System.out.println("Inside SomeInterfaceOne defaultMethod::"+inputString);
}
}
Agora, quando uma classe irá implementar o SomeInterface, não é obrigatório fornecer implementação para métodos padrão de interface.
Se tivermos outra interface com os seguintes métodos:
public interface SomeInterfaceTwo {
void usualAbstractMethod(String inputString);
default void defaultMethod(String inputString){
System.out.println("Inside SomeInterfaceTwo defaultMethod::"+inputString);
}
}
Java não permite a extensão de múltiplas classes porque resulta no "Problema do Diamante " onde o compilador não é capaz de decidir qual método superclasse usar. Com os métodos padrão, o problema do diamante irá surgir também para as interfaces. Porque se uma classe está implementando ambos
SomeInterfaceOne and SomeInterfaceTwo
e não implementa o método padrão comum, o compilador não pode decidir qual deles escolher. Para evitar este problema, no java 8 é obrigatório implementar métodos padrão comuns de diferentes interfaces. Se alguma classe está implementando ambas as interfaces acima, ela tem que prover implementação para o método defaultMethod(), caso contrário o compilador irá lançar um erro de tempo de compilação.
A sua explicação parece decente, mas talvez pareça que estava a ler tudo a partir de um livro? :-/
O que mais me incomoda é saber quão sólido foi o seu exemplo? Você se preocupou em incluir mais todas as diferenças entre o abstrato e as interfaces?
Pessoalmente, eu sugeriria este link: http://mindprod.com/jgloss/interfacevsabstract.html#TABLE
para uma lista exaustiva de diferenças...
Espero que ajude a si e a todos os outros leitores nas suas futuras entrevistas
Uma interface é um "contract" onde a classe que implementa o contrato promete implementar os métodos. Um exemplo onde eu tive que escrever uma interface ao invés de uma classe foi quando eu estava atualizando um jogo de 2D para 3D. Eu tive que criar uma interface para compartilhar classes entre a versão 2D e a 3D do jogo.
package adventure;
import java.awt.*;
public interface Playable {
public void playSound(String s);
public Image loadPicture(String s);
}
Então eu posso implementar os métodos baseados no ambiente, enquanto ainda sou capaz de chamar esses métodos de um objeto que não'não sei qual versão do jogo está carregando.
A classe pública "Adventure estende os implementos JFrame Jogáveis".
A classe pública Dungeon3D estende os implementos SimpleApplication Playable.
A classe pública Principal estende o SimpleApplication implementa o AnimEventListener, ActionListener, Jogável`
Tipicamente, no mundo do jogo, o mundo pode ser uma classe abstrata que executa métodos no jogo:
public abstract class World...
public Playable owner;
public Playable getOwner() {
return owner;
}
public void setOwner(Playable owner) {
this.owner = owner;
}