Desafio TypeScript

Sistema de funcionários com interface e modificadores

Enunciado

Crie uma interface Funcionario com os métodos calcularSalario(): number e getNome(): string. Implemente duas classes:

  • Assalariado que recebe nome (public readonly) e salarioFixo (private) e implementa Funcionario.
  • Comissionado que recebe nome (public readonly), salarioBase (private) e percentualComissao (private), e também implementa Funcionario. O salário é salarioBase + salarioBase * percentualComissao.

Ambas devem ter um método getNome() que retorna o nome. Use parameter properties para os construtores. Crie uma função imprimirSalario(f: Funcionario) que imprime Nome: [nome], Salário: R$ [salario] com duas casas decimais. Teste com um array de funcionários.

Requisitos

  • Interface Funcionario com calcularSalario e getNome.
  • Classes usam implements Funcionario.
  • Construtores usam parameter properties com modificadores de acesso.
  • imprimirSalario aceita qualquer Funcionario e formata o salário com duas casas decimais.

Código inicial

// Defina a interface e as classes

Saída esperada

Nome: Ana, Salário: R$ 5000.00
Nome: Beto, Salário: R$ 3300.00
Ver dica

A interface define o contrato. As classes devem ter os métodos exatamente com a mesma assinatura. Use toFixed(2) para formatar.

Mostrar solução
interface Funcionario {
  calcularSalario(): number;
  getNome(): string;
}

class Assalariado implements Funcionario {
  constructor(
    public readonly nome: string,
    private salarioFixo: number
  ) {}

  public calcularSalario(): number {
    return this.salarioFixo;
  }

  public getNome(): string {
    return this.nome;
  }
}

class Comissionado implements Funcionario {
  constructor(
    public readonly nome: string,
    private salarioBase: number,
    private percentualComissao: number
  ) {}

  public calcularSalario(): number {
    return this.salarioBase + this.salarioBase * this.percentualComissao;
  }

  public getNome(): string {
    return this.nome;
  }
}

function imprimirSalario(f: Funcionario): void {
  console.log(`Nome: ${f.getNome()}, Salário: R$ ${f.calcularSalario().toFixed(2)}`);
}

// Teste
const funcionarios: Funcionario[] = [
  new Assalariado("Ana", 5000),
  new Comissionado("Beto", 3000, 0.1)
];

funcionarios.forEach(imprimirSalario);

Passo a passo

  1. Definimos a interface Funcionario com os métodos calcularSalario e getNome.
  2. A classe Assalariado implementa Funcionario e usa parameter properties: public readonly nome e private salarioFixo.
  3. calcularSalario retorna o salário fixo; getNome retorna o nome.
  4. A classe Comissionado também implementa Funcionario, com salarioBase e percentualComissao privados.
  5. Seu calcularSalario soma o salário base com a comissão calculada.
  6. A função imprimirSalario recebe um Funcionario (qualquer implementação) e usa os métodos da interface.
  7. Criamos um array de Funcionario e chamamos imprimirSalario para cada um.

Por que funciona

A interface Funcionario define um contrato que ambas as classes cumprem. Isso permite tratar objetos de tipos diferentes de forma uniforme (polimorfismo). Os modificadores private garantem que os detalhes internos (como salarioFixo) não sejam acessados externamente, enquanto readonly protege o nome. As parameter properties simplificam a declaração dos campos.

Erros comuns

  • Esquecer de implementar um método da interface: Class 'Assalariado' incorrectly implements interface 'Funcionario'.
  • Declarar calcularSalario como private na classe: a interface exige que seja público; erro de compilação.
  • Tentar acessar f.salarioFixo dentro de imprimirSalario: erro porque é private.
  • Não usar toFixed(2): a saída teria apenas uma casa decimal ou nenhuma.

Outra forma de resolver

Em vez de interface, poderia ser uma classe abstrata com métodos abstratos. A interface é mais flexível pois permite herança múltipla de contratos.

Saída esperada

Nome: Ana, Salário: R$ 5000.00
Nome: Beto, Salário: R$ 3300.00