Oi Matheus, tudo bem?
Desculpe a demora em retornar.
Primeiramente, é importante entender que o polimorfismo é uma técnica da programação orientada a objetos que permite que objetos de diferentes classes possam ser tratados de forma uniforme, como se fossem do mesmo tipo. Isso é feito através da utilização de herança e/ou interfaces, onde os objetos herdam ou implementam os mesmos métodos, permitindo que possam ser tratados de forma polimórfica.
No seu caso, a classe Imprimivel é uma interface que define um método abstrato paraTexto(). Isso significa que qualquer classe que implemente essa interface deve obrigatoriamente implementar o método paraTexto(). A função imprimir() recebe um ou mais objetos que implementam a interface Imprimivel e chama o método paraTexto() de cada objeto para imprimi-lo na tela.
A partir disso, o instrutor do curso ensina o conceito de polimorfismo, mostrando como as classes Negociacao e Negociacoes podem estender a classe Imprimivel e implementar o método paraTexto(), permitindo que possam ser utilizadas como argumento da função imprimir().
No entanto, você testou o código sem estender as classes Negociacao e Negociacoes da classe Imprimivel, mas manteve a implementação do método paraTexto(). E o código funcionou corretamente, sem gerar erros na função imprimir(). Mas por quê?
Isso aconteceu porque o TypeScript é uma linguagem que permite a tipagem estática, ou seja, ele verifica o tipo dos objetos em tempo de compilação e não em tempo de execução. Portanto, se você passar um objeto que não implementa a interface Imprimivel para a função imprimir(), o TypeScript irá gerar um erro de compilação, informando que esse objeto não pode ser passado como argumento.
No seu caso, mesmo sem estender as classes Negociacao e Negociacoes da classe Imprimivel, o TypeScript identifica que essas classes implementam o método paraTexto(), que é o método exigido pela interface Imprimivel. Por isso, mesmo sem utilizar o polimorfismo de forma explícita, o TypeScript consegue identificar que essas classes podem ser tratadas como objetos do tipo Imprimivel e permite que sejam passadas como argumento para a função imprimir().
No entanto, é importante destacar que, embora o código tenha funcionado corretamente nesse caso específico, é uma boa prática utilizar o polimorfismo de forma explícita, extendendo as classes da interface Imprimivel. Isso torna o código mais legível e facilita a manutenção no futuro, já que evita erros e torna mais claro quais são os objetos que podem ser passados como argumento para a função imprimir().
Espero que tenha te ajudado.
Um abraço e bons estudos.