Introdução
O conceito de encapusalento é primordial para proteger nossas classes. Vamos ser didáticos aqui e fingir que estamos desenvolvendo um jogo de RPG. Pensa na vida (HP) do personagem como aquela barrinha vermelha no topo da tela. Se qualquer parte do código puder mexer nela direto, é fácil alguém, por engano, jogar a vida pra -500 ou deixar passar do máximo — bug feio, barra quebrada.
class Personagem
{
public string Nome { get; }
public int VidaMaxima { get; }
private int _vida; // ninguém mexe aqui de fora
public int Vida => _vida; // só leitura
public Personagem(string nome, int vidaMaxima)
{
Nome = nome;
VidaMaxima = vidaMaxima;
_vida = vidaMaxima;
}
public void TomarDano(int dano)
{
_vida = Math.Max(0, _vida - dano); // nunca fica negativo
if (_vida == 0) Console.WriteLine($"{Nome} foi derrotado!");
}
public void Curar(int quantidade)
{
_vida = Math.Min(VidaMaxima, _vida + quantidade); // nunca passa do máximo
}
}
Repara: personagem.Vida = -50; nem compila. A única forma de mexer na vida é passando pelas regras (TomarDano, Curar), que garantem que ela nunca sai do intervalo válido. Isso é encapsulamento — o dado protegido pela lógica que mora junto dele.
Um detalhe importante é: não é só "usar private", é agrupar dados e o comportamento que os manipula, escondendo os detalhes internos e expondo uma interface controlada. O objetivo é garantir que o objeto nunca fique num estado inválido.
Os dois níveis de encapsulamento
Dois níveis de encapsulamento que gente costuma confundir:
-
Data hiding — esconder os campos (
private decimal _saldo). -
Information hiding (mais amplo) — esconder a implementação, não só os dados. Exemplo: trocar a implementação interna de uma
Listade array pra lista ligada sem que ninguém que usa a classe perceba.
Nível de acesso em C
É importante e cai muito bem dominar todos, não só o public/private
public class Exemplo
{
private int _a; // só dentro da própria classe
protected int _b; // classe e subclasses
internal int _c; // mesmo assembly
protected internal int _d; // subclasses OU mesmo assembly
private protected int _e; // subclasses DENTRO do mesmo assembly
public int _f; // qualquer um
}
Erro comum
Um erro comum é expor um campo mutável de referência (lista, array) via getter público quebra o encapsulamento mesmo com private set:
class Pedido
{
private List<string> _itens = new();
public List<string> Itens => _itens; // PERIGO: quem chamar Itens.Add() muda o estado interno direto
}
O fix é retornar uma cópia ou uma interface somente-leitura: IReadOnlyList<string> Itens => _itens.AsReadOnly();
Top comments (0)