Technology Aug 29, 2026 · 2 min read

POO: Classes Concretas

Introdução Uma classe é concreta quando está 100% implementada. Nenhum membro fica pendurado sem corpo. É por isso, e so por isso que o compilador libera o new. Vamos ver a anatomia completa de uma classe concreta, com todas as peças que ela pode ter: class Carro { // Campo privad...

DE
DEV Community
by Yuri Peixinho
POO: Classes Concretas

Introdução

Uma classe é concreta quando está 100% implementada. Nenhum membro fica pendurado sem corpo. É por isso, e so por isso que o compilador libera o new.

Vamos ver a anatomia completa de uma classe concreta, com todas as peças que ela pode ter:

class Carro
{
    // Campo privado: o dado bruto, cru
    private double _combustivelLitros;

    // Propriedades: a porta de entrada controlada
    public string Placa { get; }                 // só leitura fora do construtor
    public string Modelo { get; set; }
    public double VelocidadeAtual { get; private set; } // lê de fora, só a própria classe muda

    // Membro estático e constante: pertencem à CLASSE, não a cada objeto
    public const double CapacidadeTanqueMaxima = 50.0;
    private static int _totalCarrosCriados = 0;

    // Construtor principal
    public Carro(string placa, string modelo, double combustivelInicial)
    {
        Placa = placa;
        Modelo = modelo;
        _combustivelLitros = combustivelInicial;
        _totalCarrosCriados++;
    }

    // Construtor sobrecarregado, encadeando no principal com "this(...)"
    public Carro(string placa, string modelo) : this(placa, modelo, combustivelInicial: 10)
    {
    }

    public void Acelerar(double incremento)
    {
        if (_combustivelLitros <= 0)
        {
            Console.WriteLine($"{Modelo} está sem combustível!");
            return;
        }
        VelocidadeAtual += incremento;
        _combustivelLitros -= 0.5;
    }

    public static int TotalCriados() => _totalCarrosCriados;
}

Vale destrinchar cada detalhe:

  • Placa sem set. Só pode ser atribuída dentro do construtor. Depois disso, é imutável pra sempre. É a forma mais simples de garantir que uma placa nunca muda depois de criada.
  • _totalCarrosCriados estático, ***não pertence a nenhum carro específico, pertence à *classe Carro inteira. Incrementa toda vez que qualquer carro nasce, e é compartilhado entre todas as instâncias.
  • Dois construtores — o segundo delega pro primeiro via : this(...), evitando duplicar a lógica de inicialização. É overloading de construtor, o mesmo mecanismo do overloading de método.

Instanciando:

var meuCarro = new Carro("ABC-1234", "Modelo X", combustivelInicial: 40); // usa o construtor completo
var outroCarro = new Carro("DEF-5678", "Modelo Y"); // usa o construtor curto, com 10L de combustível padrão

Quando usar só uma classe concreta, sem hierarquia nenhuma: quando não existe variação de comportamento por tipo. Se só vai existir um jeito de "Carro" existir no seu sistema — sem carro elétrico, autônomo, etc. — criar uma hierarquia complexa é over-engineering. Comece simples, só introduza abstract/interface quando a variação aparecer de verdade.

Erro comum: a "God Class" — uma classe concreta que vai crescendo e acumulando responsabilidades demais (Carro cuidando de motor, de pagamento do aluguel, de geolocalização, de manutenção...). É sintoma de que faltou dividir em outras classes menores — ligação direta com o "S" do SOLID que já vimos.

DE
Source

This article was originally published by DEV Community and written by Yuri Peixinho.

Read original article on DEV Community
Back to Discover

Reading List