Olá, Christopher. Como vai?
O seu código está excelente e a implementação do conceito de Herança em C# foi executada de forma impecável!
A herança é um dos pilares mais importantes da Programação Orientada a Objetos (POO), e você aplicou perfeitamente a sintaxe da linguagem ao usar o operador : para indicar que Passageiro estende Pessoa, além de utilizar a palavra-chave base(nome, idade) no construtor para repassar os dados obrigatórios para a classe-mãe.
Analisando a sua modelagem, o relacionamento do tipo "É um" se encaixa perfeitamente aqui: um Passageiro é uma Pessoa, o que significa que ele deve herdar naturalmente as características genéricas (como Nome e Idade) e apenas especializar o seu próprio comportamento adicionando a QuantidadeBilhetes.
Para agregar ainda mais valor ao seu aprendizado neste capítulo sobre Herança vs. Composição, vale a pena analisar como as propriedades que você criou interagem com o encapsulamento e as boas práticas modernas do C#:
- Propriedades Imutáveis (Getters puros): Ao declarar as propriedades apenas com o
get; (ex: public string? Nome { get; }), você tornou os seus objetos imutáveis após a criação pelo construtor. Essa é uma excelente prática no mercado de C# moderno, pois evita que os dados do passageiro sejam alterados acidentalmente por outras partes do sistema após o objeto ser instanciado. - Simplificação na Instanciação (C# 9+): No seu arquivo
Program.cs, você utilizou com maestria o Target-typed new expression ao escrever apenas new("Cassia", 28, 7). Isso deixa o código muito mais limpo e evita redundâncias visuais na declaração.
Para expandir a sua visão sobre o tema do capítulo, imagine o seguinte cenário de evolução do sistema: e se precisarmos gerenciar os dados do Cartão de Fidelidade do passageiro?
Nesse momento, entra o dilema entre Herança e Composição. Em vez de fazer o passageiro herdar de uma classe "Cartão" (o que violaria a lógica, pois um passageiro não é um cartão), nós aplicamos a Composição (um passageiro tem um cartão).
Veja como o seu código poderia evoluir aplicando os dois conceitos juntos (Herança + Composição):
// 1. Nova classe que será usada na composição
internal class CartaoFidelidade
{
public CartaoFidelidade(string codigo, int pontos)
{
Codigo = codigo;
Pontos = pontos;
}
public string Codigo { get; }
public int Pontos { get; }
}
// 2. Classe Passageiro combinando Herança (Pessoa) com Composição (CartaoFidelidade)
internal class Passageiro : Pessoa
{
public Passageiro(string? nome, int idade, int quantidadeBilhetes, CartaoFidelidade? cartao)
: base(nome, idade)
{
QuantidadeBilhetes = quantidadeBilhetes;
Cartao = cartao; // Composição acontecendo aqui!
}
public int QuantidadeBilhetes { get; }
public CartaoFidelidade? Cartao { get; } // Propriedade do tipo de outra classe
public void ExibirDados()
{
Console.Write($"Passageiro: {Nome} - Idade: {Idade} - Bilhetes: {QuantidadeBilhetes}");
if (Cartao != null)
{
Console.Write($" - Cartão Fidelidade: {Cartao.Codigo} (Pontos: {Cartao.Pontos})");
}
Console.WriteLine("\n");
}
}
A estrutura que você construiu originalmente serve como uma base extremamente sólida para sistemas de grande porte. Parabéns pela precisão técnica na escrita do código e por compartilhar o seu progresso no fórum!
Espero que possa ter lhe ajudado!