POO: Scope / Visibility
Introdução
Se você não escrever nenhum modificador num membro de classe, ele vira private por padrão. E se você não escrever nenhum modificador numa classe de nível superior, ela vira internal por padrão.
class Veiculo // sem "public" aqui, seria "internal" por padrão
{
double _combustivel; // sem modificador = private implícito — CUIDADO, é fácil esquecer
}
Tabela completa de todos os níveis, incluindo as combinações que ficaram de fora do desenho anterior:
| Modificador | Quem acessa |
|---|---|
private | só a própria classe |
protected | a classe e suas subclasses, em qualquer assembly |
internal | qualquer código no mesmo assembly (projeto/DLL) |
protected internal | subclasses OU mesmo assembly (união dos dois) |
private protected | subclasses E mesmo assembly ao mesmo tempo (interseção — C# 7.2+) |
public | qualquer lugar |
file (C# 11+) | só dentro do mesmo arquivo .cs — bem de nicho, usado em código gerado |
Aplicado na nossa classe:
abstract class Veiculo
{
private int _senhaAlarme = 4821; // só Veiculo enxerga, nem subclasse vê
protected double _quilometragem; // Veiculo E suas subclasses enxergam
internal string CodigoFrota = "FROTA-01"; // qualquer classe do mesmo projeto enxerga
public string Placa { get; } // literalmente qualquer um enxerga
}
Granularidade por acessor — isso é subestimado: getter e setter de uma mesma propriedade podem ter visibilidades diferentes:
public class Veiculo
{
// getter público (todo mundo lê a velocidade), setter privado (só o próprio Veiculo muda)
public double VelocidadeAtual { get; private set; }
// getter protected internal (subclasses OU mesmo assembly), setter só pra subclasses
protected internal double Odometro { get; protected set; }
}
Isso é como você escreve, no código de verdade, aquele princípio de "esconder o dado, expor uma leitura controlada" — sem precisar escrever um método GetVelocidade() manualmente.
Regra prática pra decidir:
Campo quase sempre private (exponha via propriedade se precisar); método que é só detalhe interno de implementação, private; algo que outras classes do mesmo módulo precisam mas o mundo de fora não, internal; parte do "contrato público" da sua classe, public. protected só quando você sabe que vai ter herança e a subclasse genuinamente precisa daquele acesso direto.