Olá, Christopher. Como vai?
Parabéns por concluir mais um desafio do curso! A sua implementação do sistema de pagamentos utiliza recursos muito importantes do C#, como interfaces (IPagamento), classes abstratas (Pessoa) e simulação de concorrência/atraso com o método Thread.Sleep().
Apesar de o código compilar e funcionar visualmente no console, a estrutura atual apresenta um erro conceitual grave de modelagem orientada a objetos (OO). Você utilizou a Herança em uma relação onde deveria ter aplicado a Composição.
Vamos entender a fundo o que está acontecendo e como corrigir o design do seu software.
O Erro Conceitual da Herança
No seu código, as classes foram declaradas assim:
internal class PagamentoBoleto : Pessoa, IPagamento
A regra de ouro da herança dita que a relação entre a classe filha e a classe mãe deve ser do tipo "É um". Se formos traduzir a sua linha de código para o mundo real, ela está dizendo que "Um Pagamento via Boleto é uma Pessoa".
Fazer uma forma de pagamento herdar de um ser humano quebra a lógica de herança. O correto é entender que o Pagamento é uma ação ou um documento que tem uma Pessoa associada a ele como cliente.
Como Corrigir Utilizando Composição
Para ajustar o design do seu sistema seguindo os padrões de arquitetura de mercado, o ideal é desvincular o pagamento da herança de Pessoa e transformar a pessoa em uma propriedade (um componente) interna do pagamento.
Veja abaixo como reestruturar o projeto de forma limpa e profissional:
Pessoa.cs (Mantemos como uma classe comum concreta para representar o cliente)
namespace PraticandoC_05.SistemaDePagamentos08
{
internal class Pessoa
{
public string? Nome { get; set; }
public string? Email { get; set; }
public Pessoa(string? nome, string? email)
{
Nome = nome;
Email = email;
}
}
}
PagamentoBoleto.cs (Aplicando a Composição com Pessoa)
namespace PraticandoC_05.SistemaDePagamentos08
{
internal class PagamentoBoleto : IPagamento
{
// O pagamento NÃO É uma pessoa, ele TEM uma pessoa (Composição)
public Pessoa Cliente { get; }
public PagamentoBoleto(Pessoa cliente)
{
Cliente = cliente;
}
public void ProcessarPagamento()
{
Console.WriteLine($"Processando pagamento via boleto para {Cliente.Nome} - {Cliente.Email}...");
Thread.Sleep(3000);
Console.WriteLine("Pagamento via boleto efetuado com êxito!");
}
}
}
PagamentoCredito.cs (Aplicando a Composição com Pessoa)
namespace PraticandoC_05.SistemaDePagamentos08
{
internal class PagamentoCredito : IPagamento
{
public Pessoa Cliente { get; }
public PagamentoCredito(Pessoa cliente)
{
Cliente = cliente;
}
public void ProcessarPagamento()
{
Console.WriteLine($"Processando pagamento com cartão de crédito para {Cliente.Nome} - {Cliente.Email}...");
Thread.Sleep(3000);
Console.WriteLine("Pagamento com crédito efetuado com êxito!");
}
}
}
O Novo Fluxo no Program.cs
Com essa alteração, a criação dos objetos fica muito mais organizada e realista. Primeiro criamos os clientes e, depois, associamos esses clientes aos seus respectivos pagamentos:
using PraticandoC_05.SistemaDePagamentos08;
// 1. Criamos as instâncias das pessoas
Pessoa andre = new Pessoa("André", "andre@email.com");
Pessoa juliana = new Pessoa("Juliana", "juliana@email.com");
// 2. Criamos os pagamentos injetando o cliente correspondente
IPagamento pagamento1 = new PagamentoCredito(andre);
IPagamento pagamento2 = new PagamentoBoleto(juliana);
// 3. Executamos o processamento polimórfico
pagamento1.ProcessarPagamento();
Console.WriteLine("\nPressione qualquer tecla para continuar.\n");
Console.ReadKey();
pagamento2.ProcessarPagamento();
Repare que no Program.cs reestruturado eu declarei as variáveis utilizando o tipo da interface (IPagamento pagamento1 = ...). Isso é uma excelente prática chamada Programar voltado para Interfaces, permitindo que o seu sistema trate qualquer forma de pagamento de maneira genérica e padronizada.
Fazer essa mudança vai elevar o nível do seu código e consolidar o aprendizado do capítulo sobre quando usar herança ou composição!
Espero que possa ter lhe ajudado!