Encapsulamento 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. Objetos restringem a visibilidade de seus recursos (atributos e métodos) aos outros usuários. Todo objeto tem uma interface, que determina como os outros objetos podem interagir com ele. A implementação do objeto é encapsulada, isso é, invisível ou visível fora do próprio objeto.
Public – deixa visível a classe ou membro para todas as outras classes, subclasses e pacotes do projeto Java, ou namespaces do projeto C#.
Private – deixa visível o atributo apenas para a classe em que este atributo se encontra.
Protected – deixa visível o atributo para todas as outras classes e subclasses que pertencem ao mesmo pacote ou namespace. O protected é um intermediário entre public e private.
Publico VS Private
- Publico todas as classes podem usar os métodos e campos.
- Privado apenas a classe podem usar os métodos e campos.
Por que Controlar o Acesso?
- Proteger informação privada.
- Esclarecer como outros programadores devem usar sua classe.
- Manter a implementação separado da interface.
Exemplo: imagine o seguinte cenário, temos uma classe que é responsável por transações de cartões de credito geralmente este tipo de classe pertence a companhia de cartões de credito e foi desenvolvida por um outro programador e esta dentro de uma DLL ou OS, acontece que o desenvolvedor terceirizado cometeu um deslize deixando visível a propriedade numero do cartão. Um desenvolvedor malicioso pode facilmente capturar o numero do cartão referenciando o objeto.
Neste exemplo você deve brincar com o código fonte a fim de resolver o problema de controle de acesso , use CTRL+espaço após a classe para ver a visibilidade de acesso dos métodos e campos.
Java
Classe #1 – Principal
public class Malicioso { // Assim que setar private esta void não podera ser escrita // Você não tera mais acesso as propriedades da classe static void metodoMalicioso(CartaoCredito cartao) { cartao.gastos = 0; System.out.println("Seu numero de cartão: " + cartao.numeroCartao); } public static void main(String[] args) { // Uma transação hipotetica CartaoCredito transacao = new CartaoCredito(); transacao.cobranca("3453 3636 0001 1267", 350.00); // Metodo malicioso Injeta um gasto valor de 0 e imprime o numero do cartão metodoMalicioso(transacao); } }
Classe #2 – Cartão de Credito
public class CartaoCredito { // Esta declaração esta errada // Deste modo é possive capturar o numero do cartão // A classe expos o numero para que seja acessivel de outra classe // para não expor os numero use private // private String numeroCartao; // private double gastos; public String numeroCartao; double gastos; // Em java mesmo não declarando publico a propriedade ainda é acessivel // public para a void ser vista por outras classes public void cobranca (String nCartao,double valor) { numeroCartao = nCartao; gastos = gastos + valor; } }
C#
Classe #1 – Principal
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Malicioso { class Program { // Assim que setar private esta void não podera ser escrita // Você não tera mais acesso as propriedades da classe static void metodoMalicioso(CartaoCredito cartao) { cartao.gastos = 0; Console.WriteLine("Seu numero de cartão: " + cartao.numeroCartao); } static void Main(string[] args) { // Uma transação hipotética CartaoCredito transacao = new CartaoCredito(); transacao.cobranca("3453 3636 0001 1267", 350.00); // Metodo malicioso Injeta um gasto valor de 0 e imprime o numero do cartão metodoMalicioso(transacao); Console.ReadKey(); } } }
Classe #2 – Cartão de Credito
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Malicioso { public class CartaoCredito { // Esta declaração esta errada // Deste modo é possive capturar o numero do cartão // A classe expos o numero para que seja acessivel de outra classe // para não expor os numero use private // private String numeroCartao; // private double gastos; public String numeroCartao; public double gastos; // public para a void ser vista por outras classes public void cobranca(String nCartao, double valor) { numeroCartao = nCartao; gastos = gastos + valor; } } }