Encapsulamento
| Orientação a objetos |
| Objeto |
| Classe |
| Abstração |
| Métodos |
| Atributo |
| Encapsulamento |
| Herança |
| Polimorfismo |
| Outras referências |
| Padrões de projeto |
| UML |
| Engenharia OO |
Encapsulamento vem de encapsular, que em programação orientada a objetos significa separar o programa em partes, o mais isoladas possível. A idéia é tornar o software mais flexível, fácil de modificar e de criar novas implementações[1][2].
Para exemplificar, podemos pensar em uma dona de casa (usuário) utilizando um liquidificador (sistema). O usuário não necessita conhecer detalhes do funcionamento interno do sistema para poder utilizá-lo, precisa apenas conhecer a interface, no caso, os botões que controlam o liquidificador. Outro exemplo clássico de encapsulamento é o padrão de projeto chamado Mediator.
Uma grande vantagem do encapsulamento é que toda parte encapsulada pode ser modificada sem que os usuários da classe em questão sejam afetados. No exemplo do liquidificador, um técnico poderia substituir o motor do equipamento por um outro totalmente diferente, sem que a dona de casa seja afetada - afinal, ela continuará somente tendo que pressionar o botão.
O encapsulamento protege o acesso direto (referência) aos atributos de uma instância fora da classe onde estes foram declarados. Esta proteção consiste em se usar modificadores de acesso mais restritivos sobre os atributos definidos na classe. Depois devem ser criados métodos para manipular de forma indireta os atributos da classe.
Encapsular atributos também auxilia a garantir que o estado e o comportamento de um objeto se mantenha coeso. Por exemplo, no caso da classe Semaforo poderiamos ter um método de acesso chamado lerCor(), e um modificador chamado proximaCor(). O estado é mantido pois os usuários da classe não podem alterar as cores de um semáforo ao seu bel prazer e, por exemplo, fazer a seguinte troca de cores: vermelho-amarelo-vermelho. É comum usar o padrão get<nomeDoAtributo> para o método que retorna o valor atual do atributo e set<nomeDoAtributo> para o método que modifica o valor de um atributo do objeto, como no exemplo abaixo: setComProtecao e getComProtecao. Em C# proporciona uma forma de se fazer acesso a variaveis privadas chamada Properties. Com Properties pode-se encapsular os campos assim como na forma convencional, porém quando se for acessar os mesmos pode-se fazer como se fosse uma variavel comum. Essa nova forma torna a programação mais facil e intuitiva.
Índice |
[editar] Exemplos
Os exemplos a seguir foram escritos utilizando as linguagens Java e C++ . Entretanto, a idéia aplica-se a qualquer linguagem de programação orientada a objetos. Atente ao fato de que cada linguagem de programação define os literais de palavra reservada para definir seus modificadores de acesso. Alguns tipos são: public, private e protect.
[editar] Properties em C#
public class Pessoa { //Autor: Mateus Mesquita //Data: 16 de setembro de 2011 //variaveis de instancia //por padrão com o modificador de acesso private String nome; int idade; int telefone; bool estaComprometido; //Properties que encapsulam os campos public String Nome{ get{ return nome; } //value é uma variavel local, definida //pelo compilador, sendo assim não se pode //definir dentro do bloco a seguir um varivel //chamada value. //A mesma tem o tipo implicitimente definido com //o que se eh passado a ela, na atribuição de algum //valor a essa propertie for passado o tipo int //como em objeto.Propetie = 123; //value será do tipo int //nesse caso a baixo value sera do tipo String set{ nome = value;} } public int Idade{ get{ return idade;} //Pode-se (e deve-se) ser feito a escrutinagem //de valores dentro dos blocos set{ idade = (value >= 0) ? idade : 0;} } public int Telefone{ //Pode-se chamar metodos dentro as properties //para que caso hajaa uma logica de //escrutinagem ou de acesso mais elaborada //No exemplo abaixo é apenas demostrativo get{ return GetTelefone(); } set{ telefone = value;} } public bool Comprometido{ //Pode-se também criar properties //"Read-only" ou Write-only //Fazendo assim que a mesma possa apenas //ser lida, ou apenas escrita //Neste caso a propertie é read-only //pois estaremos implementando apenas //o get da mesma get{ return estaComprometido;} } //Pode-se tambem implementar um "falso" readonly ou //writeonly, fazendo que que a propetie tenha um //set private, ou um set private. //Assim para o "mundo externo" é apenas uma propertie //de leitura ou escrita, mas para a classe é uma properie //comum /* Falso Readonly - Writeonly //Write only public int SomeVar{ private get{ return someVar;} set{ someVar = value;} } //Read only public int SomeVar{ get{ return someVar;} private set{ someVar = value;} } */ //Deve-se lembrar que sempre a propertie deve ter //o modificador de acesso mais abrangente e //ou o set, ou o get um modificador de acesso mais restrito //caso queira-se criar um "falso' Read/Write-only //Assim o proximo exemplo estara errado /* ERRADO Falso Readonly - Writeonly //Write only private int SomeVar{ public get{ return someVar;} set{ someVar = value;} } //Read only private int SomeVar{ get{ return someVar;} public set{ someVar = value;} } */ public int getTelefone(){ return telefone; } //Construtor da classe; public Pessoa(String nome, int idade, int telefone){ //Usando as properties, //Note que com esse mecanismo é como se vocé estive-se //utilizando uma variavel comum. Nome = nome; this.Idade = idade; Telefone = telefone; } }
[editar] Sem encapsulamento em JAVA
class NaoEncapsulado { // implicitamente public int semProtecao; } public class TesteNaoEncapsulado { public static void main(String[] args) { NaoEncapsulado ne = new NaoEncapsulado(); // ne é uma instância de NaoEncapsulado ne.semProtecao = 10; // acesso direto ao atributo System.out.println("Valor sem proteção: " + ne.semProtecao); // acesso direto aos atributos ou nao estupor } }
[editar] Sem encapsulamento em C++
public class NaoEncapsulado{ int primeiraVar; bool segundaVar; /// veja que temos duas variáveis com omissão do tipo de acesso : private, protected e public, }; int main() { NaoEncapsulado nEmc; nEmc.primeiraVar = 3 ;// nesse linha e a de baixo temos acesso direto aos dois atributos de class NaoEncapsulado nEmc.segundaVar = false ; cout <<" primeira variavel"<< nEmc.primeiraVar << endl; return 0; }
NOTA: Nos dois exemplos a cima, não precisamos criar nem usar nenhum método da classe NaoEncapsulado para manipular os valores dos seus atributos. O acesso direto ao atribulo de uma classe acontece também quando temos encapsulamento de acesso público; ou seja em casos que devemos usar modificador de acesso private, não devemos preocupar com a omissão do mesmo, mas para um bom senso, os programados costumam descrever os modificadores mesmo que sejam públicos.
[editar] Com encapsulamento em JAVA
class Encapsulado { // private é um modificador de acesso de restrição máxima private int comProtecao; public void setComProtecao(int valor) { comProtecao = valor; } public int getComProtecao() { return comProtecao; } } public class TesteEncapsulado { public static void main(String[] args) { Encapsulado e = new Encapsulado(); // "e" é uma instância de Encapsulado // acesso direto a um atributo protegido implicará erro de compilação e.comProtecao = 10; // deve-se acessar o atributos de forma indireta, encapsulada e.setComProtecao(10); System.out.println("Valor com proteção: " + e.getComProtecao()); } }
[editar] Com encapsulamento em C++
public class Encapsulado{ private: /// declaração dos atributos privados int primeiraVar; bool segundaVar; public: // declaração dos métodos para acesso dos atributos void setVar(int a, bool v); bool getVarSeg(void); int getVarPri(void); }; // definição dos métodos void Encapsulado::setVar(int a, bool v){ this.primeiraVar = a; this.segundaVar= v; } bool Encapsulado::getVarSeg(void){ return this.segundaVar; } int Encapsulado::getVarPri(void){ return this.primeiraVar; } int main() { Encapsulado Enc; Enc.setVar(3,false); // deve-se acessar o atributos de forma indireta: encapsulamento com acesso privado. cout <<" primeira variavel"<< Enc.getVarPri()<< endl; cout <<" primeira variavel"<< Enc.primeiraVar<< endl; // ->> acesso direto a um atributo privado gera erro na compilação return 0; }
Referências
- ↑ (em inglês) Michael Lee Scott, Programming language pragmatics, Edition 2, Morgan Kaufmann, 2006, ISBN 0126339511, p. 481: "Encapsulation mechanisms enable the programmer to group data and the subroutines that operate on them together in one place, and to hide irrelevant details from the users of an abstraction."
- ↑ (em inglês) Nell B. Dale, Chip Weems, Programming and problem solving with Java, Edition 2, Jones & Bartlett Publishers, 2007, ISBN 0763734020, p. 396