No exemplo mostrado de Imposto, poderíamos ter utilizado uma classe abstrata Imposto no lugar da interface? Qual a real diferença nesses casos? :)
No exemplo mostrado de Imposto, poderíamos ter utilizado uma classe abstrata Imposto no lugar da interface? Qual a real diferença nesses casos? :)
Interfaces nunca vão possuir implementações de seus métodos, apenas a assinatura deles. Acima de tudo, toda classe que implemente uma interface tem obrigação de implementar todos os métodos declarados.
Exemplo:
/* Exemplo de interface */
public interface Conta<T extends Banco> {
void deposita(Double valorDeposito);
void saca(Double valorDeposito);
void transfereMesmoBanco(Conta<T> conta, Double valorTransferencia);
void transfereBancoDiferente(Conta<?> conta, Double valorTransferencia);
}
/* Exemplo de implementação de interface */
public class ContaPoupanca implements Conta<Bradesco> {
private BigDecimal valor;
@Override
public void deposita(Double valorDeposito) {
valor.add(BigDecimal.valueOf(valorDeposito));
}
@Override
public void saca(Double valorDeposito) {
valor.min(BigDecimal.valueOf(valorDeposito));
}
@Override
public void transfereMesmoBanco(Conta<Bradesco> conta, Double valorTransferencia) {
saca(valorTransferencia);
conta.deposita(valorTransferencia);
}
@Override
public void transfereBancoDiferente(Conta<?> conta, Double valorTransferencia) {
valorTransferencia *= Bradesco.TAXA_TRANFERENCIA;
saca(valorTransferencia);
conta.deposita(valorTransferencia);
}
}
// Apesar de eu não ter implementado, poderia haver alguma outra classe como "ContaCorrente". Acho que deu pra pegar a ideia.
Obs.: resolvi omitir as classes Banco
e Bradesco
por estarem fora do escopo da explicação.
Classes abstratas não servem para garantir integridade em aplicações por não levarem esta obrigatoriedade aos seus herdeiros. Entretanto, nela é possível haver implementações de métodos, atributos de a classe e até mesmo é haver um construtor mesmo sendo impossível instanciá-la.
/* Exemplo de uma classe abstrata */
public abstract class Entidade {
private Integer idEntidade;
protected Entidade(Integer idEntidade) {
this.idEntidade = idEntidade;
}
public Integer getIdEntidade() {
return idEntidade;
}
}
/* Exemplo de herança */
public class Pessoa extends Entidade {
public Pessoa(Integer idEntidade) {
super(idEntidade);
}
}
De forma bem resumida, interfaces servem para garantir integridade da sua aplicação, isto é chamado de contrato de classe. As classes abstratas são geralmente utilizadas como base para uma classe herdeira.