Bom se eu deixar minhas variáveis de instâncias com public, meus usuários terão “acesso” a ele, mas mesmo se eu Encapsular as variáveis de instância com public, tem algum problema ?
Como você encapsularia algo public? Se é public não está encapsulado.
Descupe-me, mas se existe algum tipo de perolas do ano essa ai deveria entrar para as perolas de 2008.
Mano sobre ancapsulamento, as variaveis devem ser private e você deve fornecer metodos public para pega-las e seta-las. ou apenas pega-las, ou apenas seta-las…
Ademir, leia essa apostila apartir do cap 4 com carinho:
Duvida, as variaveis poderiam ser protected dependendo do caso e ainda assim estarem encapsuladas, certo?
Porque para classes fora do pacote e que não sejam subclasses da mesma, não teriam acesso.
Essa é a primeira parte, que implica em encapsular a representação interna da variável.
Você ainda tem que fornecer proteção ao conteúdo dessas variáveis e, se for o caso, também encapsular sua lógica de uso. Sem isso, não haverá encapsulamento das regras de negócio, o que é tão prejucidicial quanto não encapsular.
Portanto, o ideal é que a classe encapsule não só a representação física do atributo, mas também contenha toda a lógica de como usa-lo. Isso garante um comportamento consistente em todo sistema. E é uma das principais razões pela qual gets e sets foram criados em primeiro lugar.
Outro exemplo (que já dei várias vezes aqui), considere a seguinte classe de semáforo:
[code]
public class Semaforo {
public enum Cor {VERDE, AMARELO, VERMELHO};
private Cor cor;
public Semaforo() { cor = Cor.VERDE );
public void setCor(Cor cor) { this.cor = cor; }
public void getCor() { return cor; }
}[/code]
A presença do get e set garantem encapsulamento? Da representação física, até que sim. Poderíamos mudar o enum ali de dentro por um int, sem que os usuários da classe externa vissem, bastanto que mantivessemos os método gets e sets ainda usando a cor…
Agora a classe, desse jeito, permite que vc faça trocas de cores absurdas. Como do vermelho para o amarelo e depois para o vermelho novamente. Ou, permite até que nunca passe pelo amarelo. Além disso, provavelmente a lógica de troca de cor estará duplicada pelo seu código, já que em todos os pontos onde uma troca foi necessária, o programador teve de programa-la.
Novamente, a parte física do atributo está encapsulada, mas sua lógica não. O correto mesmo seria eliminar o método setter e trocar para um método chamado trocaCor(). Esse método trocaria cores sempre na ordem correta. Se um dia essa ordem mudasse, bastaria alterar esse método (e não diversos pontos no programa).
Há uma discussão interessante sobre esse tema (de onde parte desse post foi copiado) neste site.
[quote=GustavoLaguna]Duvida, as variaveis poderiam ser protected dependendo do caso e ainda assim estarem encapsuladas, certo?
Porque para classes fora do pacote e que não sejam subclasses da mesma, não teriam acesso.[/quote]
Uma boa regra é tratar variáveis protected e default como não encapsuladas. Claro, elas são menos vulneráveis do que as públicas, mas ainda assim, existe total liberdade para que classes do mesmo pacote, ou classes filhas (no caso da protected) as modifique. Também pode haver classes que estejam dependendo diretamente da sua representação interna, portanto, pode ser difícil alterar o tipo dessa variável sem modificar outros trechos de código.
Alguns autores até recomendam que os modificadores protected e default sejam usados apenas para métodos, não para atributos.
Atributos seriam sempre private. Eu acho essa afirmação um tanto radical e nunca tive muitos problemas com variáveis protegidas ou default. Até porque, meus pacotes são pequenos e as hierarquias de classes da minha aplicação não são extensas. Graças a isso, mesmo que exista necessidade de modificação, geralmente é numa pequena porção de código, o que é plenamente administrável. Mas é sempre bom lembrar que é um risco que se corre e um trecho onde se deve prestar atenção.