Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

Solucionado
(ver solução)
1
resposta

[Projeto] Faça como eu fiz: cálculo de juros para diferentes perfis de empréstimo

Classe Program:

List<IEmprestimo> perfis = new()
{
    new EmprestimoEstudante(),
    new EmprestimoEmpresario(),
    new EmprestimoAposentado()
};

foreach (var perfil in perfis)
{
    decimal total = perfil.CalcularValorFinal(1000m, 12);
    Console.WriteLine($"{perfil.GetType().Name}: R$ {total:N2}");
}

Interface IEmprestimo:

namespace Polimorfismo.JurosEmprestimo;

internal interface IEmprestimo
{
    public decimal CalcularValorFinal(decimal valorEmprestado, int meses);
}

Classe EmprestimoEstudante:

namespace Polimorfismo.JurosEmprestimo;

internal class EmprestimoEstudante : IEmprestimo
{
    public decimal CalcularValorFinal(decimal valorEmprestado, int meses)
    {
        decimal taxa = 0.01m;
        return valorEmprestado + (valorEmprestado * taxa * meses);
    }
}

Classe EmprestimoEmpresario:

namespace Polimorfismo.JurosEmprestimo;

internal class EmprestimoEmpresario : IEmprestimo
{
    public decimal CalcularValorFinal(decimal valorEmprestado, int meses)
    {
        decimal taxa = 0.025m;
        return valorEmprestado + (valorEmprestado * taxa * meses);
    }
}

Classe EmprestimoAposentado:

namespace Polimorfismo.JurosEmprestimo;

internal class EmprestimoAposentado : IEmprestimo
{
    public decimal CalcularValorFinal(decimal valorEmprestado, int meses)
    {
        decimal taxa = 0.015m;
        return valorEmprestado + (valorEmprestado * taxa * meses);
    }
}
1 resposta
solução!

Olá, Fabiano. Como vai?

Excelente implementação do desafio! O seu código demonstra uma evolução muito legal no entendimento do Polimorfismo, utilizando uma Interface (IEmprestimo) em vez de uma classe base com métodos virtuais.

Essa abordagem usando interfaces é uma das melhores práticas no ecossistema C# e no desenvolvimento de software em geral. Enquanto a herança de classe dita o que um objeto é, a interface dita o que um objeto faz (um contrato). Ao criar a lista List<IEmprestimo>, você unificou o comportamento de cálculo de valor final para perfis completamente diferentes (EmprestimoEstudante, EmprestimoEmpresario e EmprestimoAposentado), permitindo que o laço foreach chame a regra correta de cada um de forma dinâmica em tempo de execução.

Para agregar ainda mais valor ao seu projeto e trazer conceitos de Clean Code e arquitetura, separei duas sugestões de melhoria bem interessantes:

1. Simplificando a declaração da Interface

A partir das versões mais recentes do C# (C# 8+), o modificador public passou a ser aceito dentro de interfaces para indicar escopos específicos, mas por padrão, todos os membros de uma interface já são implicitamente públicos.

Uma boa prática de estilo para manter o código enxuto é omitir o modificador public na assinatura do método dentro da interface. Veja a diferença:

namespace Polimorfismo.JurosEmprestimo;

internal interface IEmprestimo
{
    // O 'public' pode ser omitido, pois o contrato já é público por natureza
    decimal CalcularValorFinal(decimal valorEmprestado, int meses);
}

2. Evitando "Números Mágicos" e usando Inicialização de Expressão

Dentro das suas classes filhas, você criou variáveis locais para definir a taxa (ex: decimal taxa = 0.01m;). Isso é ótimo para evitar números jogados direto no cálculo, mas como essas taxas são fixas e imutáveis por perfil, o ideal é transformá-las em campos de leitura exclusivos (private const ou private readonly).

Além disso, em métodos curtos que possuem apenas uma linha de retorno, podemos utilizar a sintaxe moderna de Expression-bodied members (membros com corpo de expressão =>), deixando o código muito mais limpo e elegante.

Veja como a classe EmprestimoEstudante ficaria aplicando essas práticas:

namespace Polimorfismo.JurosEmprestimo;

internal class EmprestimoEstudante : IEmprestimo
{
    // Taxa definida como constante privada da classe
    private const decimal TaxaMensal = 0.01m;

    // Uso do operador => para retorno direto em uma única linha
    public decimal CalcularValorFinal(decimal valorEmprestado, int meses) 
        => valorEmprestado + (valorEmprestado * TaxaMensal * meses);
}

Aplicando essa mesma reestruturação nas classes do empresário e do aposentado, o seu projeto ganhará um ganho imenso de legibilidade, aproximando-se do padrão de escrita utilizado em grandes projetos profissionais de C#.

A estrutura lógica do seu simulador de empréstimos está impecável. Continue com esse excelente foco em Orientação a Objetos!

Espero que possa ter lhe ajudado!