Getters e setters

###### << Anterior - Home - Próxima >>

Os atributos de uma classe muito raramente são públicos. Um atributo público pode ser modificado a partir de qualquer ponto do programa e a classe não tem nenhum controle sobre as alterações em seu conteúdo e portanto não pode garantir sua validade. Tornar um atributo público significa abrir mão do controle sobre esse atributo e isso vai completamente contra toda a filosofia e o objetivo da POO. Então o acesso direto aos atributos deve sempre ser restrito associando a eles os modificadores private ou protected. Isso impede que o conteúdo dos atributos seja alterado sem o controle da classe.

Por outro lado, atributos não são constantes e pode haver a necessidade de modificar seu conteúdo. Então deve existir uma maneira permitir a alteração do conteúdo dos atributos por entidades externas à classe, desde que a classe tenha controle suficiente sobre essa alteração para poder garantir a validade do atributo.

A maneira de resolver essa situação é criar métodos especializados em dar um acesso controlado aos atributos. Estes métodos são chamados de **getters** e **setters**. O **get** de um atributo retorna o seu conteúdo e o **set** permite sua alteração. Note que se o setter de um atributo for o único modo de uma entidade externa à classe modificar seu conteúdo, a classe pode implementar no setter qualquer validação que seja necessária e decidir se aceita ou não a alteração que está sendo feita. Veja o exemplo abaixo, usando a classe Pessoa.

**Exemplo:**

```
public class Pessoa {
 private String nome;
 private int idade;

 // Construtor
 public Pessoa(String vNome, int vIdade) {
   nome = vNome;
   idade = vIdade;
 }

 // Getters
 public String getNome() {
   return nome;
 }

 public int getIdade() {
   return idade;
 }

 // Setters
 public void setNome(String value){
   if(!value.isEmpty()) nome = value;
 }

 public void setIdade(int value){
   if(value >= 0) idade = value;
 }

} // classe Pessoa

```

No exemplo acima, os dois atributos da classe são privados, portanto não é possível ter acesso direto a eles de fora da classe. Apesar disso é possivel que outras classes possam obter o valor dos atributos através dos métodos **getNome** e **getIdade**. Caso outra classe precise alterar o valor de algum atributo, isso é possível usando os métodos **setNome** ou **setIdade**, ***desde que as condições impostas pelos métodos sejam satisfeitas.*** O método **setNome** não aceita uma string vazia e o método **setIdade** não aceita um valor negativo.

## **Dicas e casos especiais**

**Use o netbeans:** O netbeans sabe como programar getters e setters básicos, então deixe-o fazer isso. No arquivo fonte da classe, clique com o botão direito em qualquer linha dentro da classe, mas fora de qualquer método (por exemplo entre dois métodos), escolha a opção "Inserir código" e depois "Getter e setter". O netbeans irá mostrar uma janela com todos os atributos da classe e então basta selecionar os atributos que o netbeans se encarrega de escrever o código básico dos getters e setters para os selecionados.

**Mas cuidado!!!** Não vá enfiando getters e setters públicos no programa sem necessidade. Só faça se for realmente necessário e depois de avaliar o impacto sobre o funcionamento da classe. Existem casos em que o atributo não pode ter getters ou setters (pelo menos não públicos), por que isso acaba com os controles internos da classe. Um exemplo típico é uma classe que gerencia uma conta corrente e tem como um de seus atributos o saldo da conta. A classe oferece métodos para depositar e para sacar dinheiro da conta e estes métodos atualizam o valor do saldo. Se o atributo para o saldo tiver um setter, todo esse mecanismo de depósitos e saques perde o sentido. Neste caso o saldo não pode ter um setter.

**Uso interno:** Alguns atributos podem ser necessários apenas para controle interno da classe e não há motivo para que sejam acessados externamente. Neste caso não é necessário (e nem aconselhável) implementar getters e setters para eles, ou caso sejam implementados, devem ficar com acesso privado ou protegido. Só ofereça getters e/ou setters públicos se isso for realmente necessário.

**Read only:** Se quiser que algum atributo seja apenas para leitura, basta tornar o setter dele privado e deixar o getter público.

**Atributos "virtuais":** Getters e setters não precisam necessariamente ter correspondência com os atributos declarados na classe. Considere o getter abaixo para a classe Pessoa:

```
public class Pessoa {

 ...

 public String getFaixaEtaria() {
   if(idade < 12) return "Criança";
   else
     if(idade < 18) return "Adolescente";
     else
       return "Adulto";
 }

} // classe Pessoa

```

Neste exemplo, não existe realmente um atributo para a faixa etária da pessoa, essa informação é calculada a partir da idade. Mas as outras classes não sabem e não precisam saber disso.

**Armadilha:** Falando em informações calculadas, um erro bastante comum para quem está iniciando na POO é declarar atributos cujo conteúdo é resultado de um cálculo ou processo feito a partir de outros atributos. Se uma informação é resultado de um cálculo ou processo, então deve ser implementado um método que retorne essa informação e não armazená-la em um atributo, assim como foi feito no exemplo anterior para a faixa etária.

### **Links recomendados:**

* Como não aprender Java e Orientação a Objetos: getters e setters (Caelum)