Solucionado (ver solução)
Solucionado
(ver solução)
6
respostas

Aula 5 - Contas compatíveis

Boa noite,

Para percorrer e imprimir todas as contas, criei uma interface onde a "ContaComum" e "ContaDeEstudante" implementam ela. Dessa forma consigo listar, pois todas são um tipo de "conta".

É errado esse tipo de abordagem? O método "rende" da interface tem na "ContaDeEstudante", porém sem implementação.

Caio no mesmo problema da herança?

Existe outra forma?

Obrigado,

6 respostas

Henrique Winckler, longe de mim ser um expert, afinal também estou fazendo este curso, mas acredito que seu conceito esteja correto, afinal vc implementou na interface um método comum para ambas.

Acredito que se é um método comum para ambos os contextos vc utilizar a interface não seria um problema.

Afinal imprimir é algo comum de conta, ou seja toda conta imprimi certo ?

Olá Henrique,

Também não sou um expert, mas deixar um método sem implementação apenas para obter o uso do polimorfismo não me parece uma boa ideia, pois você está quebrando justamente o contrato que toda interface é, ou seja, não está fornecendo a implementação daquele método.

Olá,

Também não achei muito elegante.

Alguma outra ideia?

Abs

solução!

Boa noite Henrique, A meu mer, a melhor forma seria utilizando composição, pois mesmo que utilize a implementação com interfaces, tanto a classe ContaEstudante quanto a classe ContaComum teriam de controlar suas operações individualmente, ou seja, temos duplicação de código, já que cada classe controlaria saque, deposito, rendimento e outros. No final de tudo, teríamos duas contas fazendo a mesma coisa. Outra opção seria utilizar uma classe abstrata que faria o trabalho do 'ManipuladorDeSaldo'.

Não podemos render uma conta de estudante, então não faz sentido ela estar no processador de investimentos.

Se você quer fazer com que uma conta renda por exemplo, crie uma interface do tipo "ContaComRendimento" que tenha o método render e no for apenas contas com rendimento poderiam ser processadas.

Fiz algo usando implementação de (de interfaces) e composição.

package br.com.schimidtsolutions.estudo.solid.lsp;

public interface Conta {

    void depositar(double valor);

    void sacar(double valor);

    double getSaldo();
}

package br.com.schimidtsolutions.estudo.solid.lsp;

public interface ContaNaoRentavel extends Conta {

    int getMilhas();
}

package br.com.schimidtsolutions.estudo.solid.lsp;

public interface ContaRentavel extends Conta{

    void render();
}

package br.com.schimidtsolutions.estudo.solid.lsp;

public class ContaComum implements ContaRentavel {
    private ManipuladorSaldo manipuladorSaldo;

    public ContaComum() {
        manipuladorSaldo = new ManipuladorSaldoPadrao();
    }

    @Override
    public void depositar(double valor) {
        manipuladorSaldo.deposita(valor);
    }

    @Override
    public void sacar(double valor) {
        manipuladorSaldo.saca(valor);
    }

    @Override
    public void render() {
        manipuladorSaldo.rende(0.01);
    }

    @Override
    public double getSaldo() {
        return manipuladorSaldo.getSaldo();
    }
}

package br.com.schimidtsolutions.estudo.solid.lsp;

public class ContaDeEstudante implements ContaNaoRentavel{
    private ManipuladorSaldo manipuladorSaldo;
    private int milhas;

    public ContaDeEstudante() {
        manipuladorSaldo = new ManipuladorSaldoPadrao();
    }

    @Override
    public void depositar(double valor) {
        manipuladorSaldo.deposita(valor);
        this.milhas += (int)valor;
    }

    @Override
    public void sacar(double valor) {
        manipuladorSaldo.saca(valor);
    }

    @Override
    public double getSaldo() {
        return manipuladorSaldo.getSaldo();
    }

    @Override
    public int getMilhas() {
        return milhas;
    }
}

package br.com.schimidtsolutions.estudo.solid.lsp;

public interface ManipuladorSaldo {

    void deposita(double valor);

    void saca(double valor);

    void rende(double percentualRendimento);

    double getSaldo();

}

package br.com.schimidtsolutions.estudo.solid.lsp;

public class ManipuladorSaldoPadrao implements ManipuladorSaldo {
    private double saldo;

    public ManipuladorSaldoPadrao() {
        this.saldo = 0;
    }

    @Override
    public void deposita(double valor) {
        this.saldo += valor;
    }

    @Override
    public void saca(double valor) {
        if (valor <= this.saldo) {
            this.saldo -= valor;
        } else {
            throw new IllegalArgumentException();
        }
    }

    @Override
    public void rende(double percentualRendimento) {
        this.saldo += this.saldo * percentualRendimento;
    }

    @Override
    public double getSaldo() {
        return saldo;
    }
}