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

Override quando vale a pena usar?

Quando vale a pena usar o método Override?

No meu projeto quis adicionar uma taxa para transferências, no valor de 10 reais. Para fazer isso, sobrescrevi o método transfere da classe Conta, para a classe Conta Corrente.

Porém, usando a anotação, a única forma que encontrei para efetuar a taxa de 10 reias e transferir o valor inserido, foi adicionando o método saca.

* Código Comentado * Quando não uso o anotação Override, e apenas sobrescrevo o método "manualmente" consigo alterar a estrutura dele e apenas adicionar o valor de 10 reias.

Em algum momento esse código pode ser problemático? Alguém sabe outra forma em que pode ser executado?

Classe Conta



public class Conta {

    private double saldo;
    private int agencia;
    private int numero;
    private Cliente titular;
    private static int totalContas;

    public Conta(int agencia, int numero) {

        if(agencia <= 0) {
            System.out.println("A Agência não pode ser menor ou igual a 0");
            return;
        } this.agencia = agencia;

        if (numero <= 0 ) {
            System.out.println("O Número não pode ser menor ou igual a 0");
            return;
        } this.numero = numero;
        System.out.println("Conta criada com sucesso!");
        Conta.totalContas++;
    }

    public void deposita(double valor) {

        this.saldo += valor;
    }

    public boolean saca(double valor) {

        if(this.saldo >= valor) {
            this.saldo -= valor;    
            return true;
        } else {
            System.out.println("Saldo insuficiente! Operação não realizada.");
            return false;
        }
    }

    public boolean transfere(double valor, Conta destino) {

                if(saca(valor)) {
                destino.deposita(valor);
                return true;
                } return false;
            }

    public double getSaldo() {
        return this.saldo;

    }

    public int getNumero() {
        return this.numero;
    }

    public int getAgencia() {
        return this.agencia;
    }

    public Cliente getTitular() {
        return this.titular;
    }

    public void setTitular(Cliente titular) {
        this.titular = titular;
    }

    public static int getTotalContas() {
        return Conta.totalContas;
    }

}

Classe Conta Corrente


public class ContaCorrente extends Conta {

    public ContaCorrente(int agencia, int numero) {
        super(agencia, numero);
    }

//    public boolean transfere(double valor, Conta destino) {
//        
//        if(saca(valor + 10)) {
//            destino.deposita(valor);
//            return true;
//        } else {
//            return false;
//        }
//    }

    @Override
    public boolean transfere(double valor, Conta destino) {
        saca(10);
        return super.transfere(valor, destino);
    }

    @Override
    public boolean saca(double valor) {
        double taxaSaque = valor + 0.20;
        return super.saca(taxaSaque);
    }


}

Classe TestaConta


public class TestaConta {

    public static void main(String[] args) {

        ContaCorrente cc = new ContaCorrente(1990, 12345);
        cc.deposita(100);

        System.out.println("Saldo CC: " + cc.getSaldo());

        ContaPoupanca cp = new ContaPoupanca(2020, 54321);
        cp.deposita(200);

        System.out.println("Saldo CP: " + cp.getSaldo());

        cc.transfere(10, cp);
        System.out.println("Saldo CC: " + cc.getSaldo());
        System.out.println("Saldo CP: " + cp.getSaldo());


    }

}
3 respostas
solução!

Olá Alvaro, tudo bem com você?

Ambas as maneiras parecem funcionar, mas por que o método que você comentou não poderia ficar com a anotação @Override também?

    @Override
    public boolean transfere(double valor, Conta destino) {     
        if(saca(valor + 10)) {
            destino.deposita(valor);
            System.out.println("tranfere de cc");
            return true;
        } else {
            return false;
        }
    }

Na minha opinião, usar o método saca() no método transfere() da ContaCorrente não parece ser tão bacana já que nós não estamos de fato sacando dinheiro, mas sim aplicando uma taxa de 10 reais, correto? Que tal se passarmos a taxa como argumento do método super.transfere():

    @Override
    public boolean transfere(double valor, Conta destino) {
        // saca(10);
        return super.transfere(valor + 10, destino);
    }

Dessa forma, caso precisemos alterar algo no método saca() futuramente, não vamos quebrar o código que cobra os 10 reais também!

Mas respondendo a sua pergunta, sempre que possível quando queremos sobrescrever um método da classe mãe, nós vamos optar por usar o @Override para garantir que o método da classe filha está, de fato, sobrescrevendo um método existente. Não sei se consegui ser claro, mas dá uma olhada nesse outro tópico onde eu tento dar um exemplo disso: tópico.

Se algum ponto não fez sentido, por favor, me avise! ;)

Forte abraço e bons estudos!!

Olá Thiago, muito obrigado pelo sua resposta, foi esclarecedor!

Porém, me sobrou uma dúvida, em relação ao código que você sugeriu para o método transfere sobrescrito.

@Override
    public boolean transfere(double valor, Conta destino) {
        // saca(10);
        return super.transfere(valor + 10, destino);
    }

Eu não posso simplesmente adicionar o valor de +10, da forma que você me sugeriu, por que o valor de 10 reais e uma taxa que o banco cobra. Da forma em que o código está escrito, a Conta destino receberá o valor informado como parâmetro mais o valor de 10 reais.

Por isso, a única solução que eu havia encontrado era simplesmente chamando o método saca(10) no meio do método transfere.

Estou correto das afirmações que fiz, ou não?

Aguardo retorno

Opa Alvaro, bem observado!! hahah'

Realmente, você está 100% correto. Da forma como eu acabei de fazer eu só troquei um problema por outro - para a sorte da conta destino que ganhava 10 reais do banco.

Só para esclarecer, o motivo para eu não querer usar o método saca() aqui é porque da forma como está, se uma conta for fazer uma transferência, será cobrada da conta de origem o valor da taxa de transferência (10) + valor da taxa de saque(0.20). Detalhe que a taxa de saque será cobrada duas vezes: uma no método transfere() da ContaCorrente e outra no mesmo método da classe Conta na linha if(saca(valor)). Pior que nem o código que eu te mandei resolve esse problema da taxa de saque. hehe

Se nas regras de negócio for aceitável cobrar duas taxas diferentes para uma mesma operação, tudo bem. Mas caso o método transfere() deva ter apenas uma única taxa de 10 reais como você definiu, então isso significado que o método transfere() não deve ser mais composto pela combinação do saca() com taxa de 0.2 + deposita(). Portanto, veja se fazendo dessa outra forma faz mais sentido:

Método transfere()

@Override
public boolean transfere(double valor, Conta destino) {
    if (this.saldo + 10 >= valor) { // verifica se a conta de origem tem saldo suficiente
        this.saldo -= valor + 10; // cobra a taxa de 10 reais
        destino.deposita(valor); // deposita apenas o valor retirado da conta sem a taxa
        return true;
    }
    return false;
}

Perceba que esse método é simplesmente uma forma alterada do método saca(). Tudo para evitar usar o método saca() que cobraria uma taxa extra da conta de origem. Ficou um pouco feio, não? Bom, se o objetivo é evitar a taxa do método saca(), então que tal usarmos o método saca() da classe Conta, já que ela não cobra nenhuma taxa?

Método transfere() chamando o super.saca()

@Override
public boolean transfere(double valor, Conta destino) {
    if (super.saca(valor + 10)) { // verifica o saldo e cobra a taxa
        destino.deposita(valor); // deposita o valor sem a taxa
        return true;
    }
    return false;
}

Dessa forma, evitamos qualquer contato com o método saca() da ContaCorrente, ao mesmo tempo em que continuamos com ele disponível para ser usado e alterado sem entrar no caminho da lógica por trás do método transfere().

Sempre existe a possibilidade para melhorias na lógica do código, mas me diz aí o que achou. Fez sentido para você fazer dessa forma ou tem algum ponto que talvez possamos mudar? Qualquer coisa estou à disposição! Abraços!!