DEV Community

Gabriel_Silvestre
Gabriel_Silvestre

Posted on

Introdução ao Polimorfismo

Tabela de Conteúdo


Polimorfismo

O que é?

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.

O que faz?

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.

Tipos

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.

Voltar ao topo


Sobrescrita de Métodos

O que é?

É 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.

Sintaxe

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.

class Person {
  constructor(public name: string) {}

  move(): void {
    console.log(`${this.name} se move`);
  }
}
Enter fullscreen mode Exit fullscreen mode
class Runner extends Person {
  move() {
    console.log(`${this.name} corre`);
  }
}

class Lazy extends Person {
  move() {
    console.log(`${this.name} anda devagar`);
  }
}
Enter fullscreen mode Exit fullscreen mode
const john = new Person('John');
const runnerJohn = new Runner('John');
const lazyJohn = new Lazy('John');

john.move();  // John se move
runnerJohn.move();  // John corre
lazyJohn.move();  // John anda devagar
Enter fullscreen mode Exit fullscreen mode

Voltar ao topo


Classes Abstratas

O que são?

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.

Sintaxe

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.

abstract class Person {
  constructor(public name: string) {}

  /*
  mesmo estando em uma classe abstrata, ainda podemos criar métodos comuns
  que não precisam ser obrigatoriamente implementados nas Sub Classes.
  */
  greetings() {
    console.log(`Eu me chamo ${this.name}`);
  }

  abstract move(): void;
}
Enter fullscreen mode Exit fullscreen mode
class Runner extends Person {
  move() {  // o método abstrato precisa ser implementado nas Sub Classes
    console.log(`${this.name} corre`);
  }
}

class Lazy extends Person {
  move() {
    console.log(`${this.name} anda devagar`);
  }
}
Enter fullscreen mode Exit fullscreen mode
const runnerJohn = new Runner('John');
const lazyJohn = new Lazy('John');

runnerJohn.move();  // John corre
runnerJohn.greetings();  // Eu me chamo John

lazyJohn.move();  // John anda devagar
lazyJohn.greetings();  // Eu me chamo John
Enter fullscreen mode Exit fullscreen mode

Voltar ao topo


Métodos Estáticos

O que são?

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.

Sintaxe

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;
  }

  static get size() {
    return this.groupSize;
  }
}
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode

Voltar ao topo


Polimorfismo em Interfaces

O que é?

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.

Sintaxe

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> {
  title: string;
  platform: string;
  controls: T;
}
Enter fullscreen mode Exit fullscreen mode
type FPSControls = {
  W: 'up',
  A: 'left',
  S: 'down',
  D: 'right',
}

class FPSGame extends IGame<FPSControls> {
  constructor(
    public title: string,
    public platform: string,
    public controls: FPSControls
  ) {}
}
Enter fullscreen mode Exit fullscreen mode
type MOBAControls = {
  Q: 'firstAbility',
  W: 'secondAbility',
  E: 'thirdAbility',
  R: 'ultimate',
}

class MOBAGame extends IGame<MOBAControls> {
  constructor(
    public title: string,
    public platform: string,
    public controls: MOBAControls
  ) {}
}
Enter fullscreen mode Exit fullscreen mode

Voltar ao topo


Links Úteis

Voltar ao topo

Discussion (0)