Podemos referenciar classes que implementam essa interface, por exemplo: ITributavel t = new ContaPoupanca();
Podemos referenciar classes que implementam essa interface, por exemplo: ITributavel t = new ContaPoupanca();
Olá, Felipe!
a variável de objeto t
é do tipo ITributavel
, ou seja, ela só pode conter objetos de classes que implementam a interface ITributavel
.
Podemos escrever:
ITributavel t = new ContaPoupanca();
Mas também poderíamos escrever
ContaPoupanca t = new ContaPoupanca();
As duas maneiras estão corretas. Mas qual a diferença? A diferença é que ITributavel t
pode conter ContaPoupanca
, mas também poderia conter objeto de outra classe que implementa ITributavel
, como por exemplo ContaCorrente
:
ITributavel t = new ContaCorrente();
Essa forma acima também está certa! Agora, o que acontece se escrevermos:
ContaPoupanca t = new ContaCorrente();
?
Nesse caso, teremos um erro de compilação, pois a declaração ContaPoupanca t
nos obriga a instanciarmos um objeto do tipo específico ContaPoupanca
. Não podemos atribuir um ContaCorrente
a uma variável que foi definida como outro tipo.
Pense dessa forma: a variável declarada como ITributavel
é mais "genérica", mais "tolerante" e "flexível". Uma variável declarada como ContaPoupanca
é mais "específica", "exigente" e "inflexível".
Espero ter ajudado. Boa sorte e bons estudos!
Boa tarde Felipe,
Baseado nesta ótima resposta do Marcelo, pense o seguinte: o Polimorfismo é a capacidade de um objeto ter várias formas não é? Vamos enxergar o polimorfismo desta situação:
ContaPoupanca pode ser instanciada, e este objeto pode ser referenciado por várias formas, como por exemplo:
Conta c = new ContaPoupanca(); //assumindo que há uma herança aqui
// e também
ITributavel t = new ContaPoupanca();
Com essa flexibilidade explicada pelo Marcelo, você ganha algo muito poderoso: a capacidade de implementar comportamentos que teriam que ocorrer para diversos objetos escrevendo um código genérico, exemplo:
public void calcularTributo(ITributavel tributavel) {
// lógica de calcular um tributo
}
O cálculo de um Tributo ocorre para uma ContaPoupanca? Sim. Então basta passar ela para o objeto que faz isso, e devido ao contrato com a interface será possível realizar o comportamento. Agora ContaCorrente também tem tributo? Sim. Basta assinar o contrato com a interface que vai servir. Agora Cheque (que nem é um tipo de Conta) tem tributo? Mesma coisa. Assina o contrato com a interface e manda bala.
Você não precisará de um objeto que implemente um comportamento próprio para ContaPoupanca, e outro para ContaCorrente, e outro para Cheque, assim:
public void calcularTributo(ContaPoupanca tributavel) {
// lógica de calcular um tributo de ContaPoupanca
}
public void calcularTributo(ContaCorrente tributavel) {
// lógica de calcular um tributo de ContaCorrente
}
public void calcularTributo(Cheque tributavel) {
// lógica de calcular um tributo de Cheque
}
Conseguiu visualizar o que o Polimorfismo traz de vantagem para uma linguagem orientada a objetos? Mais simplicidade no desenvolvimento de uma solução, reaproveitamento de código, não repete coisa que não precisa, etc.
Abraço.