[quote=tiagomac] :shock: Olá Senhores,
Fiz essa pergunta na última aula que tive de LOO1 e o professor rodou, rodou mas não respondeu… talvez vocês possam me explicar algo além do que ele disse “é design pattern, encapsulamento, tem que seguir as normas…”
Não sei se ele não respondeu por não saber mais técnicamente ou talvez porque não quis responder mesmo, mas ainda assim a dúvida continua, sei que é design pattern, até mesmo no eclipse tem uma opção para gerar automaticamente os getters e setters da class… mas técnicamente falando, porque criamos 2 metodos para trabalhar com cada variável se poderiamos atribuir e pegar o valor delas diretamente por um nomeobj.Variavel sendo ela public???
Abraços.
[/quote]
Vc poderia escrever uma classe assim :
public class Pessoa{
public XDate nascimento;
}
E usar assim:
Pessoa x = new Pessoa ();
x.nascimento= new XDate(1956,5,17); // XDate é uma classe fictica
O Java deixa vc fazer isso. vc não é obrigado a usar get e set
Mas ao não usar get e set vc está criando problemas para si mesmo porque não está encapsulando o estado do objeto. É aqui que entram considerações mais importantes que simples codificação.
O principio do encapsulamento afirma que ninguém pode aceder ao estado de um objeto exceto ele próprio.
Isso significa que teremos que criar métodos no objecto para que outros objectos obtenham os dados e tornar o estado privado.
public class Pessoa{
private XDate nascimento;
public void attribuiDataNascimento(XDate data){
this.nascimento= data;
}
public XDate obtemDataNascimento(){
return nascimento.
}
}
// uso
Pessoa x = new Pessoa ();
x.attribuiDataNascimento(new XDate(1956,5,17));
O nome do método é o que vc quiser. O Java não obriga vc a usar nenhum nome especial nem nenhuma palavra reservada extra; mantendo assim a sintaxe do java exuta. Estes métodos que acessam ou alteram o estado do objeto chamam-se Acessors (Acessores) e Modifiers (Modificadores) , respectivamente.
Bom, mas pense que existem milhões de programadores java e cada um pode dar o nome que quiser… isso é bom ,mas o java oferece ferramentas de reflection que para funcionarem têm que ser baseada numa referencia que todo o mundo use. Além disso codigo padronizado é mais facil de ler e alterar. Junte a isso o openSource e verá que cada um usar o nome que quiser é ruim.
Dai a convenção de usar o nome da variável prefixado com get ou set.
Essa convensão faz parte do Design Pattern JavaBean, mas não é em si mesma um Design Pattern , é uma convensão para obdecer ao principio de encapsulamento.
Como já foi dito não é obrigatorio que existam os dois. O estado pode ser read-only (apenas leitura), write-only (apenas escrita) ou ambos.
Mas o objeto oferecer informações que não fazem parte do seu estado, como informações calculadas. Nesse caso o método não deve ser precedido de get. Exemplo
public class Pessoa{
private XDate nascimento;
public void attribuiDataNascimento(XDate data){
this.nascimento= data;
}
public XDate obtemDataNascimento(){
return nascimento.
}
public int idade(){
return XDate.hoje().anosPassadosDesde(nascimento);
}
}
A idade da pessoa muda conforme o tempo passa. Para a calcular eu preciso acessar o estado interno do objecto para saber quando a pessoa nasceu, eu poderia usar obtemDataNascimento() e fazer os calculos cada vez que precisasse, mas isso violaria outro principio chamado DRY (don’t repeat yourself : Não se repita). Fazendo o calculo fora do objecto eu teri a que escrever muitas vezes aquele codigo, colocando-o dentro do objecto fica muito mais simples. Mas como idade é calculada , ela não é uma propriedade do objecto Pessoa, então ela não começa com get. Começar com get significaria que getIdade() é um método de acesso, e isso não seria verdade. Exemplo : o método size() da interface Collection.
Na prática vc pode usar get tb nesses casos. É uma questão de principio e não de implementação.
Então porquê get / set
- para obdecer ao principio do encapsulamento do estado.
- os nomes são convensões popularizadas pelo design pattern JavaBean, mas eles em si mesmos não são design patterns , nem os métodos. (se a variável é boolean o getXXX é substituido por isXXX)
- Não é obrigatório ter o par get/set para cada propriedade. Isso depende se a propriedade é só de leitura, só de escrita, ou ambas.
- Resultados de cálculos ou outras operações complexas não começam com get. Exemplo : o método size() da interface Collection. Mas esta regra pode não ser usada.