No exemplo mostrado de Imposto, poderíamos ter utilizado uma classe abstrata Imposto no lugar da interface? Qual a real diferença nesses casos? :)
Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!
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.