13
respostas

Atribuição de valores nos clientes.

Estou com problemas para atribuir valores ao cliente. Não entendi muito bem essa forma de atribuição por "setters".

public class PrimeiraConta {
    public static void main(String[] args) {
        Conta primeiraConta = new Conta();

        primeiraConta.setAgencia(2552);
        primeiraConta.setNumero(221);
        primeiraConta.deposita(1500.0);
        primeiraConta.setTitular(new Cliente());

        primeiraConta.setNome("Arthur");
        primeiraConta.titular.setCpf("252.361.486");
        primeiraConta.titular.setProfissao("duno");

    }
}
13 respostas

Bom dia Arthur!

Os setters são métodos que servem para atribuir valores aos respectivos atributos, evitando acesso direto aos atributos propriamente ditos.

Um conceito importante de Orientação a Objetos é o de encapsulamento, você não deve ter acesso aos atributos de uma Classe de fora dela, nem precisa saber como as coisas funcionam por baixo dos panos.

Os getters e setters são métodos padronizados para acessar os atributos, visto que eles não podem, nem devem, ser acessados diretamente.

No seu caso, você instanciou uma Conta:

Conta primeiraConta = new Conta();

Depois instanciou um Cliente (titular dessa Conta):

primeiraConta.setTitular(new Cliente());

Não seria possível atribuir um nome ao titular (Cliente) da Conta assim:

primeiraConta .getTitular().nome = "Arthur";

Sacou?

Oi Arthur, qual é o problema exatamente?

Lembra, o setter é um método como outro qualquer que tem um papel bem simples, ele recebe um valor por parâmetro e atribui esse valor ao atributo do objeto.

É um caminho indireto.

A classe Cliente fiz de acordo com o exercício, mas não saquei como preencher isso.

Consigo atribuir valores à conta, com o setAgencia(), mas se tento com os dados do cliente, não consigo.

public class Cliente {
    private String nome;
    private String cpf;
    private String profissao;

    public void setNome(String nome) {
        this.nome = nome;
    }

    public void setCpf(String cpf) {
        this.cpf = cpf;
    }

    public void setProfissao(String profissao) {
        this.profissao = profissao;
    }


    public String getNome() {
        return nome;
    }

    public String getCpf() {
        return cpf;
    }

    public String profissao() {
        return profissao;
    }
}

Usei um caminho alternativo, funciona,

public class PrimeiraConta {
    public static void main(String[] args) {
        Conta primeiraConta = new Conta();

        primeiraConta.setAgencia(2552);
        primeiraConta.setNumero(221);
        primeiraConta.deposita(1500.0);


        Cliente Arthur = new Cliente();
        Arthur.setNome("Arthur");
        Arthur.setCpf("225.365.586");
        Arthur.setProfissao("Agente de organização");

        primeiraConta.setTitular(Arthur);

        System.out.println(Arthur.getNome());

    }
}

Boa tarde Arthur!

Seu código da Clase Cliente tem alguns erros:

public class Cliente {
    private String nome;
    private String cpf;
    private String profissao;

    public void setNome(String nome) {
        this.nome = nome;
    }

    public void setCpf(String cpf) {
        this.cpf = cpf;
    }

    public void setProfissao(String profissao) {
        this.profissao = profissao;
    }

    public String getNome() {
        return nome; //erro aqui!
    }

    public String getCpf() {
        return cpf; //erro aqui!
    }

    public String profissao() { //erro aqui!
        return profissao; //erro aqui!
    }
}

O correto é assim:

public class Cliente {
    private String nome;
    private String cpf;
    private String profissao;

    public void setNome(String nome) {
        this.nome = nome;
    }

    public void setCpf(String cpf) {
        this.cpf = cpf;
    }

    public void setProfissao(String profissao) {
        this.profissao = profissao;
    }

    public String getNome() {
        return this.nome;
    }

    public String getCpf() {
        return this.cpf;
    }

    public String getProfissao() {
        return this.profissao;
    }
}

Seu teste:

public class PrimeiraConta {
    public static void main(String[] args) {
        Conta primeiraConta = new Conta();
        primeiraConta.setAgencia(2552);
        primeiraConta.setNumero(221);
        primeiraConta.deposita(1500.0);

        Cliente Arthur = new Cliente();
        Arthur.setNome("Arthur");
        Arthur.setCpf("225.365.586");
        Arthur.setProfissao("Agente de organização");

        primeiraConta.setTitular(Arthur);

        System.out.println(Arthur.getNome());
    }
}

Está válido.

Mas ficaria melhor renomear o nome da Classe para TestePrimeiraConta.

Opa Jonas, o uso do this é opcional nos casos que você citou como erro, atenção nisso tá bem? O nome dos métodos também, é convenção usar o get no nome, mas não é errado não usar.

Beleza Wanderson! Obrigado pela correção! :-)

Jonas, você diz: "Os setters são métodos que servem para atribuir valores aos respectivos atributos, evitando acesso direto aos atributos propriamente ditos."

Minha opinião bem sincera: um setter é uma forma de você ter acesso direto a um atributo, permitindo a manipulação da estrutura de uma classe. Manipulação da estrutura de classe é uma violação dos parâmetros de encapsulamento.

Se eu preciso definir um parâmetro, eu prefiro fazer ele no construtor, ou o construtor chamando métodos privados internos da classe para definir tais parametros.

Por fim, existindo a necessidade de alterar os parâmetros de uma classe, é preferível instanciar a classe do zero com os novos parâmetros que ficar manipulando a estrutura do meu objeto.

Boa noite Gustavo! Como o Wanderson falou: "É um caminho indireto."

Você pode precisar definir um valor para um atributo sem ser no momento da instanciação do objeto. Exemplo: quando uma Conta é criada o saldo dela é zero.

Você falou em "métodos privados internos da classe", mas a idéia é que os métodos sejam públicos, inclusive os getters e setters.

Não faz sentido criar uma nova instância toda vez que o valor de um atributo mudar. O objeto pode nascer com alguns valores definidos, faz todo sentido uma Conta ser criada já se sabendo qual sua agência e seu número, mas se o saldo for mudar, pra quê eu criaria um novo objeto? Não seria melhor e mais simples eu apenas mudar o valor do atributo?

Enfim, obrigado pela resposta!

É muito bom podermos aprender uns com os outros!

:-)

A propósito, para poder responder seu questionamento, eu reli esse artigo:

http://blog.caelum.com.br/nao-aprender-oo-getters-e-setters/

E li esse também:

http://blog.caelum.com.br/revisitando-a-orientacao-a-objetos-encapsulamento-no-java/

E a parte que eu mais gostei:

"No fim, a real utilidade do private é esconder acesso de atributos que precisam ser acessados de maneira mais inteligente. Mas veja que de nada adianta colocar todos os atributos como private e criar getters e setters para todos eles. Deixamos o encapsulamento “vazar” do mesmo jeito."

Jonas, getters e setter não é um caminho indireto, é um caminho que não deve ser feito dentro do princípio de OO.

vamos considerar uma implementação simples de um objeto que só retorna um valor int.

Por motivo de força do projeto você sai do primitivo int para um tipo primitivo long. O seu projeto todo está em cima de um objeto simples com um getter/setter que trabalhava com um INT.

Se você precisou operar n vezes esse objeto usando o get público em outras classes, você terá n erros de compilação, erros de apresentação dos dados, ou até mesmo os métodos de outras classes param de funcionar sem nenhum erro só de mudar o int para long.

imagina então sair de primitivo para referencia?

olha esse artigo de 2003 e 2004 (!) sobre getters/setters: https://www.javaworld.com/article/2073723/core-java/why-getter-and-setter-methods-are-evil.html

https://www.javaworld.com/article/2072302/core-java/more-on-getters-and-setters.html

e sim, faz todo sentido você instanciar uma classe para representar o valor certo. o q você não usa mais o garbage collector vai descartar.

Olá, Arthur,

Acredito que o seu objetivo com esse post é o seu interesse no preenchimento dos atributos de um objeto Cliente passando como referencial o objeto de Conta, correto?

Nos posts, percebi que não adicionou a classe Conta, mas acredito que um dos seus atributos seja: private Cliente cliente;

Para preencher um atributo de um objeto do tipo Cliente através da Conta, o mais usual seria: primeiraConta.getTitular().setNome("Athur"); primeiraConta.getTitular().setCpf("225.365.586"); primeiraConta.getTitular().setProfissao("Agente de organização");

E não dessa forma:

Cliente Arthur = new Cliente(); Arthur.setNome("Arthur"); Arthur.setCpf("225.365.586"); Arthur.setProfissao("Agente de organização"); primeiraConta.setTitular(Arthur);

Analisando o código primeiraConta.getTitular().setNome("Athur"); Primeiro você chama a referência do objeto primeiraConta depois o atributo da classe Conta que pretende preencher getTitular(). Perceba que getTitular(), além de ser referência a um atributo, também é uma referência à classe Cliente. Dessa forma, o próximo passo é referenciar o atributo da classe Cliente que se quer editar, setNome("Athur").

Espero ter ajudado! Qualquer coisa estamos aqui! :)

Att. Karen