Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Visibilidade de Atributos - implementação do método equals

Olá pessoal,

Na Aula 04 - Equals e mais listas, parte 1, por volta de 09min15s, o instrutor implementa primeiramente o método "ehIgual", que recebe como parâmetro a referência a um objeto Conta (Conta outra). Minha dúvida está relacionada aos acessos aos atributos, como os que ele fez na comparação abaixo:

public boolean ehIgual(Conta outra) {
    if (this.agencia != outra.agencia) {
       return false;
    }
    if (this.numero != outra.numero) {
       return false;
    }
}

Notem que os acessos são feitos diretamente aos atributos do objeto outra (outra.agencia e outra.numero), recebido por referência no método. Quando é implementado o método equals, primeiramente é feito um typecast para a classe específica:

Conta outra = (Conta) ref;

E novamente o acesso é feito diretamente aos atributos, que são declarados como private nesta classe Conta. Entendo que trata-se de um objeto da classe Conta fazendo uma comparação com outro objeto da mesma classe, mas o fato do atributo ser private não deveria impedir este acesso direto, mesmo sendo objetos da mesma classe? Eu havia entendido que o acesso deveria ser feito exclusivamente pelos métodos, mesmo nestes casos.

O que me deixou ainda mais intrigado é o fato de que todos os atributos ficam expostos não só para leitura, mas também para escrita. Testei o seguinte código dentro do método equals():

@Override
public boolean equals(Object ref) {

    Conta outra = (Conta) ref;
    if (outra.saldo >= 0.01) {
        outra.saldo -= 0.01;
        this.saldo += 0.01;
    }

    if(this.agencia != outra.agencia) {
        return false;
    } 
    if(this.numero != outra.numero) {
        return false;
    }
    return true;
}

E funcionou, o código permitiu "sacar" um centavo de qualquer conta que seja referenciada pelo equals sem utilizar os métodos saca e deposita, simplesmente manipulando o atributo saldo.

Enfim, é isso mesmo? Obrigado!

1 resposta
solução!

Oi Marcelo, tudo bem?

O private protege seus membros do acesso direto fora da classe onde eles foram declarados, portanto o acesso através de métodos continua valendo já que apenas quem pertence à mesma classe pode "enxergar" os detalhes de outras instâncias. Mas pelo o que eu entendi, você estava pensando em algo mais próximo de um modificador de acesso à nível de objeto, com a comunicação entre diferentes objetos(independente da classe) ocorrendo apenas através de métodos, correto?

É uma boa questão a se levantar! Porém, se analisarmos mais a fundo, vemos que um acesso restrito a nível de objeto ao invés de classe, acabaria tendo o efeito inverso e quebraria o princípio do encapsulamento!

Pensa comigo como ficaria o método equals() caso não pudéssemos acessar o atributo outra.agencia. Provavelmente precisaríamos declarar um método que buscasse essa informação, certo? Algo como um getter! Mas perceba que agora, toda vez que quiséssemos acessar um membro de outro objeto da mesma classe, teríamos que declarar um novo getter público, o que no final transformaria nossa classe Conta em uma Classe fantoche, deixando ela totalmente exposta para o resto do sistema! D:

Portanto, o importante aqui é lembrar que o encapsulamento não se trata de esconder os detalhes de uma classe de tudo e todos, mas sim de saber quem no sistema realmente necessita conhecer os detalhes. O que é o caso das instâncias de Conta, onde não há a necessidade de esconder seus membros, já que como eu mencionei anteriormente, no final das contas, todos os objetos tem acesso aos detalhes da Conta e isso não prejudica em nada no encapsulamento.

No caso onde você "sacou" dinheiro da Conta sem usar um outro método, isso acontece por estarem na mesma classe - lembrando que private apenas evita que membros de uma classe sejam acessados fora dela. Claro, alterar os valores dos atributos de outro objeto diretamente - sendo que nós já temos o método transfere() que faz isso por nós - não é uma prática recomendada.

Espero ter ajudado, se ficou qualquer dúvida é só avisar!

Bons estudos!!