Introdução ao Polimorfismo - DEV Community
Primeiros Passos: Orientação a Objeto + SOLID (5 Part Series)
1 Introdução a Orientação a Objeto 2 Introdução a Heranças e Interfaces 3 Introdução ao Polimorfismo 4 Introdução ao SOLID - Princípios S O D 5 Introdução ao SOLID - Princípios L e I
Polimorfismo em Interfaces
Na programação, o Polimorfismo remete a capacidade de alterar o comportamento de determinado método de uma Super Classe em qualquer uma das Sub Classes que à herdem.
Como dito em sua definição, permite a alteração de comportamentos de um determinado método sem alterar sua assinatura, dessa forma podemos ter o mesmo método com diferentes comportamentos a depender da classe que o implementa.
Um exemplo disso seria os métodos de ciclo de vida no React, ao trabalharmos o React com classes definimos os métodos de ciclo de vida com diferentes comportamentos dependendo do componente, porém esses métodos continuam a ter o mesmo nome, parâmetros e tipo de retorno.
Existem diferentes tipos de Polimorfismo dentro da POO (Programação Orientada a Objetos), porém nesse artigo iremos abordar apenas a Sobrescrita de Métodos com TypeScript.
É a alteração do comportamento padrão de um método da Super Classe para um comportamento mais específico de uma Sub Classe, sendo que, se não o sobrescrevermos o método manterá o comportamento definido na Super Classe.
Para sobrescrevermos um determinado método, tudo que precisamos fazer é instanciá-lo na Sub Classe e definirmos uma nova lógica.
Uma obervação, os parâmetros e o tipo de retorno do método a ser sobrescrito podem ser mantidos, no intuito de padronizar o método, sendo a única alteração, a lógica interna.
console.log(`${this.name} se move`);
class Runner extends Person {
console.log(`${this.name} corre`);
class Lazy extends Person {
console.log(`${this.name} anda devagar`);
const runnerJohn = new Runner('John');
const lazyJohn = new Lazy('John');
john.move();  // John se move
runnerJohn.move();  // John corre
lazyJohn.move();  // John anda devagar
São classes que atuam de forma similar a Interfaces, isso porque elas não podem ser instanciadas, apenas herdadas, possibilitando ainda a criação de métodos abstratos, esses que por sua vez só podem existir em Classes Abstratas e devem ser implementados em qualquer Sub Classe de uma Super Classe Abstrata.
A diferença de Classes Abstratas e Interfaces, é que nas classes podemos definir outros métodos e atributos que não são abstratos, ou seja, podem receber funcionalidade e valores.
Para definirmos Classes/Métodos Abstratos utilizamos a palavra reservada abstract antes de suas definições.
Lembrando que tudo que for abstrato, não pode ser implementado, apenas definido, e nada nos impede de criarmos métodos comuns dentro de Classes Abstratas.
mesmo estando em uma classe abstrata, ainda podemos criar métodos comuns
que não precisam ser obrigatoriamente implementados nas Sub Classes.
console.log(`Eu me chamo ${this.name}`);
abstract move(): void;
move() {  // o método abstrato precisa ser implementado nas Sub Classes
runnerJohn.greetings();  // Eu me chamo John
lazyJohn.greetings();  // Eu me chamo John
São métodos que não interagem com as instancias da classe, ou seja, manipulam as informações ligadas a classe em si, não a instância.
Também existem os atributos estáticos que assim como os métodos estão vinculados a classe e não as instâncias.
Para definirmos Métodos/Atributos Estáticos utilizamos a palavra reservada static antes de suas definições.
class GroupMember {
private static groupSize = 0;
constructor(public newPerson: string) {
Group.addMember();
private static addMember() {
this.groupSize += 1;
return this.groupSize;
console.log(GroupMember.size);  // 0
const member1 = new GroupMember('John');
console.log(GroupMember.size);  // 1
const member2 = new GroupMember('John');
console.log(GroupMember.size);  // 2
Assim como nas classes, as Interfaces também podem ser polimorfas, ou seja, ter diferentes comportamentos a depender da implementação. Esse é o comportamento padrão de toda a Interface, afinal só definimos a assinatura, parâmetros e retorno do método, enquanto a lógica interna fica por nossa conta.
Porém podemos ainda utilizar das Generics criar classes e até funções ainda mais dinâmicas, dessa forma o tipo será determinado no momento de sua criação e não na definição.
Como dito acima, o comportamento padrão de métodos definidos na Interface é serem polimórficos, logo sua definição continua a mesma.
Já para utilizarmos Generics, tudo que precisamos fazer é nós utilizar dos símbolos de maior e menor <>, colocando entre eles uma letra por convenção em maiúsculo.
interface IGame<T> {
controls: T;
type FPSControls = {
W: 'up',
A: 'left',
S: 'down',
D: 'right',
class FPSGame extends IGame<FPSControls> {
public platform: string,
public controls: FPSControls
type MOBAControls = {
Q: 'firstAbility',
W: 'secondAbility',
E: 'thirdAbility',
R: 'ultimate',
class MOBAGame extends IGame<MOBAControls> {
public controls: MOBAControls
TypeScript docs - Abstract Classes
TypeScript docs - Static Members
TypeScript docs - Generic Classes
DevMedia - Polimorfismo
Introdução aos Filter Operators
#mongodb #beginners #braziliandevs
#beginners #mongodb #braziliandevs
Once suspended, gabrielhsilvestre will not be able to comment or publish posts until their suspension is removed.
Once unsuspended, gabrielhsilvestre will be able to comment and publish posts again.
Once unpublished, all posts by gabrielhsilvestre will become hidden and only accessible to themselves.