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:
-
Placasemset. 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. -
_totalCarrosCriadosestático, ***não pertence a nenhum carro específico, pertence à *classeCarrointeira. 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.
This article was originally published by DEV Community and written by Yuri Peixinho.
Read original article on DEV Community