Olá galera, imaginemos uma classe abstrata com, e somente com, métodos abstratos. O que diferencia esta classe de uma interface?
Em termos conceptuais, nada.
Uma classe abstracta APENAS com métodos abstractos é na realidade (conceptualmente) uma interface: apenas define o contrato de quem a implementar (ou extender neste caso).
A diferença poderá estar nas implementações: podes ter uma classe a implementar 2 (ou mais) interfaces mas apenas a extender 1 classe.
Além do que já foi dito acima, uma classe abstrata pode ter campos e um construtor, uma interface não. Ex:
public abstract class ClasseAbstrata {
protected int id;
protected String nome;
public ClasseAbstrata(int id, String nome) {
this.id = id;
this.nome = nome;
}
public abstract void fazAlgo();
}
Lembrando que, por ser abstrata, ela não pode ser instanciada (new ClasseAbstrata(1, "abc")
nem sequer compila). Mas então pra que serve esse construtor?
Simples, ele pode ser reaproveitado pelas sub-classes:
public class ClasseConcreta extends ClasseAbstrata {
// pode ter campos adicionais
private String outroCampo;
public ClasseConcreta(int id, String nome, String outroCampo) {
super(id, nome); // reaproveita o construtor da super-classe
this.outroCampo = outroCampo;
}
@Override
public void fazAlgo() {
// posso acessar os campos da super-classe
System.out.printf("id=%d, nome=%s, outro=%s\n", this.id, this.nome, this.outroCampo);
}
}
Ou seja, a ideia é que a classe abstrata contém o “esqueleto” básico. Por exemplo, campos que eu sei que toda sub-classe vai ter. Com interfaces, isso não é possível, pois elas não podem ter campos.
Uma classe abstrata representa uma relação de tipos forte. Onde o filho é um tipo específico do pai. Por isso, mesmo que por hora ele não tenha nenhum atributo e todos os seus métodos sejam abstratos, ele ainda pode ter durante a evolução do projeto e os filhos herdarão essa implementação. Por isso, você só pode ter uma super classe.
Já a interface representa apenas um contrato, ou seja, um compromisso com um comportamento. Por isso, você pode implementar várias interfaces, em qualquer altura da hierarquia, e não há problemas caso haja “colisões” de comportamentos. A relação de tipos aqui é bem mais fraca, sendo preferível as classes abstratas.