DEV Community

Adriana Ferreira Lima Shikasho
Adriana Ferreira Lima Shikasho

Posted on

Olha que legal minha conversa com o ChatGPT sobre Polimorfismo no Javascript

🙋🏻‍♀️ Eu: - Me dê um exemplo de polimorfismo usando Javascript.

🤖 ChatGPT: - Claro! Aqui está um exemplo de polimorfismo em JavaScript:

// Classe base
class Animal {
  constructor(name) {
    this.name = name;
  }

  makeSound() {
    console.log("O animal faz um som.");
  }
}

// Subclasse que estende a classe Animal
class Dog extends Animal {
  makeSound() {
    console.log("O cachorro late.");
  }
}

// Subclasse que estende a classe Animal
class Cat extends Animal {
  makeSound() {
    console.log("O gato mia.");
  }
}

// Função que recebe um objeto Animal e chama o método makeSound
function makeAnimalSound(animal) {
  animal.makeSound();
}

// Criando instâncias das classes Dog e Cat
const dog = new Dog("Rex");
const cat = new Cat("Whiskers");

// Chamando a função makeAnimalSound com diferentes objetos
makeAnimalSound(dog); // Saída: "O cachorro late."
makeAnimalSound(cat); // Saída: "O gato mia."
Enter fullscreen mode Exit fullscreen mode

Nesse exemplo, temos uma classe base chamada Animal com um método makeSound. Em seguida, temos duas subclasses, Dog (cachorro) e Cat (gato), que estendem a classe base Animal e substituem o método makeSound para produzir o som específico de cada animal.

A função makeAnimalSound recebe um objeto do tipo Animal (que pode ser uma instância de Dog ou Cat) e chama o método makeSound do objeto. Dependendo do tipo do objeto passado, o método makeSound apropriado será executado.

Isso é polimorfismo, onde diferentes objetos podem responder de maneira diferente ao mesmo método, permitindo um código mais flexível e reutilizável.


🙋🏻‍♀️ Eu: - É possível aplicar polimorfismo na programaçao funcional?

🤖 ChatGPT: - Na programação funcional, o conceito de polimorfismo é um pouco diferente do exemplo anterior, pois não há classes ou herança como na programação orientada a objetos.

No entanto, é possível obter um comportamento polimórfico usando funções de alta ordem (higher-order functions) e passando funções como parâmetros.

Aqui está uma adaptação do exemplo anterior para demonstrar o polimorfismo em programação funcional:

// Função polimórfica que recebe uma função como argumento
function makeAnimalSound(animalFn) {
  return animalFn();
}

// Funções específicas para diferentes sons de animais
function dogSound() {
  console.log("O cachorro late.");
}

function catSound() {
  console.log("O gato mia.");
}

// Utilizando a função polimórfica com diferentes funções
makeAnimalSound(dogSound); // Saída: "O cachorro late."
makeAnimalSound(catSound); // Saída: "O gato mia."
Enter fullscreen mode Exit fullscreen mode

Neste exemplo, temos a função makeAnimalSound que recebe uma função como argumento (animalFn). Essa função é polimórfica, pois pode receber diferentes funções específicas para diferentes sons de animais.

As funções dogSound e catSound são exemplos de funções específicas para diferentes sons de animais. Cada uma dessas funções produz um som específico quando é chamada.

Ao chamar a função makeAnimalSound com diferentes funções (dogSound e catSound), obtemos resultados diferentes, cada um correspondendo ao som específico do animal.

Assim, conseguimos obter um comportamento polimórfico ao passar diferentes funções para a função makeAnimalSound na programação funcional.


🙋🏻‍♀️ Eu: - Podemos dizer então, que a classe é polimorfica quando recebe diferentes classes como argumento?

🤖 ChatGPT: - Sim, podemos dizer que uma classe é polimórfica quando ela recebe diferentes classes como argumento.

No contexto da programação orientada a objetos, o polimorfismo é alcançado por meio do conceito de herança e da capacidade de uma classe base tratar objetos de suas subclasses de maneira uniforme.

Quando uma classe base pode receber diferentes objetos de suas subclasses e chamar métodos com o mesmo nome, mas com implementações específicas em cada subclasse, dizemos que a classe base é polimórfica.

Vamos adaptar o exemplo do animal para ilustrar esse conceito:

// Classe base
class Animal {
  constructor(name) {
    this.name = name;
  }

  makeSound() {
    console.log("O animal faz um som.");
  }
}

// Subclasse que estende a classe Animal
class Dog extends Animal {
  makeSound() {
    console.log("O cachorro late.");
  }
}

// Subclasse que estende a classe Animal
class Cat extends Animal {
  makeSound() {
    console.log("O gato mia.");
  }
}

// Função que recebe um objeto Animal e chama o método makeSound
function makeAnimalSound(animal) {
  animal.makeSound();
}

// Criando instâncias das classes Dog e Cat
const dog = new Dog("Rex");
const cat = new Cat("Whiskers");

// Chamando a função makeAnimalSound com diferentes objetos
makeAnimalSound(dog); // Saída: "O cachorro late."
makeAnimalSound(cat); // Saída: "O gato mia."
Enter fullscreen mode Exit fullscreen mode

Neste exemplo, a classe Animal é polimórfica, pois pode receber diferentes objetos de suas subclasses Dog e Cat.

A função makeAnimalSound recebe um objeto do tipo Animal como argumento e chama o método makeSound do objeto.

Quando chamamos a função makeAnimalSound passando um objeto dog, o método makeSound da classe Dog é executado, produzindo o som específico do cachorro.

Da mesma forma, quando passamos um objeto cat, o método makeSound da classe Cat é executado, produzindo o som específico do gato.

Dessa forma, a classe Animal é polimórfica porque pode tratar diferentes objetos de suas subclasses de maneira uniforme e executar o comportamento apropriado para cada subclasse.


🙋🏻‍♀️ Eu: - Por favor, me dê um exemplo usando uma classe Product

🤖 ChatGPT: - Claro! Aqui está um exemplo usando a classe Product (Produto) para ilustrar o polimorfismo:

// Classe base
class Product {
  constructor(name, price) {
    this.name = name;
    this.price = price;
  }

  calculateDiscount() {
    return 0; // sem desconto por padrão
  }
}

// Subclasse que estende a classe Product
class SaleProduct extends Product {
  constructor(name, price, discountPercentage) {
    super(name, price);
    this.discountPercentage = discountPercentage;
  }

  calculateDiscount() {
    return (this.price * this.discountPercentage) / 100;
  }
}

// Subclasse que estende a classe Product
class ClearanceProduct extends Product {
  constructor(name, price, clearancePrice) {
    super(name, price);
    this.clearancePrice = clearancePrice;
  }

  calculateDiscount() {
    return this.price - this.clearancePrice;
  }
}

// Função que recebe um objeto Product e calcula o desconto
function calculateProductDiscount(product) {
  const discount = product.calculateDiscount();
  console.log(`O desconto do produto ${product.name} é de ${discount} reais.`);
}

// Criando instâncias das classes SaleProduct e ClearanceProduct
const saleProduct = new SaleProduct("Camiseta", 50, 20); // 20% de desconto
const clearanceProduct = new ClearanceProduct("Calça", 100, 70); // preço de liquidação de 70 reais

// Chamando a função calculateProductDiscount com diferentes objetos
calculateProductDiscount(saleProduct); // Saída: "O desconto do produto Camiseta é de 10 reais."
calculateProductDiscount(clearanceProduct); // Saída: "O desconto do produto Calça é de 30 reais."
Enter fullscreen mode Exit fullscreen mode

Nesse exemplo, temos uma classe base chamada Product com um método calculateDiscount, que retorna o desconto do produto (ou zero, se não houver desconto).

Em seguida, temos duas subclasses, SaleProduct (Produto em promoção) e ClearanceProduct (Produto em liquidação), que estendem a classe base Product e substituem o método calculateDiscount para calcular o desconto de acordo com as regras específicas de cada subclasse.

A função calculateProductDiscount recebe um objeto do tipo Product (que pode ser uma instância de SaleProduct ou ClearanceProduct) e chama o método calculateDiscount do objeto para obter o valor do desconto.

Ao criar instâncias das subclasses SaleProduct e ClearanceProduct e chamar a função calculateProductDiscount com essas instâncias, obtemos resultados diferentes, dependendo do tipo do objeto.

O método calculateDiscount apropriado é executado para cada subclasse, fornecendo o valor de desconto correto para cada produto.

Dessa forma, o exemplo ilustra o polimorfismo na classe Product, onde diferentes objetos podem responder ao mesmo método de maneira diferente, permitindo um código mais flexível e reutilizável.


🙋🏻‍♀️ Eu: - Me dê o mesmo exemplo usando functions

🤖 ChatGPT: - Claro! Aqui está um exemplo usando funções em vez de classes para ilustrar o polimorfismo:

// Função base
function calculateDiscount(product) {
  return 0; // sem desconto por padrão
}

// Função para calcular o desconto de um produto em promoção
function calculateSaleDiscount(product) {
  return (product.price * product.discountPercentage) / 100;
}

// Função para calcular o desconto de um produto em liquidação
function calculateClearanceDiscount(product) {
  return product.price - product.clearancePrice;
}

// Objeto representando um produto em promoção
const saleProduct = {
  name: "Camiseta",
  price: 50,
  discountPercentage: 20, // 20% de desconto
};

// Objeto representando um produto em liquidação
const clearanceProduct = {
  name: "Calça",
  price: 100,
  clearancePrice: 70, // preço de liquidação de 70 reais
};

// Função que recebe um objeto produto e uma função de desconto e calcula o desconto
function calculateProductDiscount(product, discountFunction) {
  const discount = discountFunction(product);
  console.log(`O desconto do produto ${product.name} é de ${discount} reais.`);
}

// Chamando a função calculateProductDiscount com diferentes objetos e funções de desconto
calculateProductDiscount(saleProduct, calculateSaleDiscount); // Saída: "O desconto do produto Camiseta é de 10 reais."
calculateProductDiscount(clearanceProduct, calculateClearanceDiscount); // Saída: "O desconto do produto Calça é de 30 reais."
Enter fullscreen mode Exit fullscreen mode

Nesse exemplo, temos funções separadas para calcular o desconto de diferentes tipos de produtos. A função calculateDiscount é a função base que retorna o desconto padrão de zero.

As funções calculateSaleDiscount e calculateClearanceDiscount são exemplos de funções específicas para calcular descontos de produtos em promoção e em liquidação, respectivamente.

Em vez de usar classes, utilizamos objetos para representar os produtos em promoção e em liquidação.

A função calculateProductDiscount recebe um objeto de produto e uma função de desconto como argumentos. Ela chama a função de desconto passando o objeto de produto e retorna o valor do desconto.

Ao chamar a função calculateProductDiscount com diferentes objetos de produto e funções de desconto correspondentes, obtemos resultados diferentes, cada um correspondendo ao desconto específico do tipo de produto.

Dessa forma, conseguimos obter um comportamento polimórfico ao passar diferentes objetos de produto e funções de desconto para a função calculateProductDiscount.

Cada função de desconto é executada para o tipo de produto apropriado, fornecendo o valor de desconto correto.


🙋🏻‍♀️ Eu: - Polimorfismo de uma function tem a ver com abstração de código?

🤖 ChatGPT: - Sim, o polimorfismo em funções está relacionado à abstração de código. O polimorfismo permite tratar diferentes objetos ou tipos de dados de maneira uniforme, ocultando detalhes específicos de implementação e fornecendo uma interface abstrata para interagir com eles.

Ao utilizar o polimorfismo, podemos escrever código genérico que pode lidar com diferentes tipos de dados ou objetos, sem se preocupar com os detalhes específicos de cada um. Isso leva a um código mais flexível, modular e reutilizável.

Quando aplicamos o polimorfismo em funções, podemos passar diferentes objetos ou tipos de dados como argumentos para a mesma função, permitindo que a função opere de maneira polimórfica em cada um deles. A função pode tratar esses objetos ou tipos de dados de forma abstrata, chamando métodos comuns ou aplicando operações genéricas a eles.

Essa abstração de código oferecida pelo polimorfismo permite que você escreva funções genéricas que podem ser reutilizadas com diferentes objetos ou tipos de dados, promovendo uma melhor modularidade, flexibilidade e capacidade de extensão do código.

Portanto, o polimorfismo em funções desempenha um papel importante na abstração de código, permitindo que você escreva código mais genérico, modular e flexível, ao tratar diferentes objetos ou tipos de dados de forma uniforme.


🙋🏻‍♀️ Eu: - Por exemplo, em uma aplicação em React, recebemos produtos da api e precisamos converter seu preço (number) para o valor da moeda do país selecionado. Posso considerar essa function localeCurrency como uma function polimórfica?

🤖 ChatGPT: - Sim, você pode considerar a função localeCurrency nesse cenário como uma função polimórfica. O polimorfismo ocorre quando uma função pode operar em diferentes tipos de dados ou objetos de maneira uniforme.

No seu exemplo em uma aplicação React, a função localeCurrency recebe um número (preço) e converte esse valor para a moeda específica com base no país selecionado.

Essa função pode ser aplicada a diferentes produtos e realizar a conversão da moeda corretamente, independentemente do tipo de produto ou do valor do preço.

A função localeCurrency é polimórfica porque ela pode ser usada com diferentes números (preços) e fornecer a conversão adequada para cada um deles, independentemente do tipo específico do produto.

Ao utilizar a função localeCurrency em diferentes contextos, você está tratando diferentes objetos (produtos) de maneira uniforme, aplicando a mesma lógica de conversão de moeda a cada um deles.

Essa capacidade de tratar diferentes objetos de forma genérica e aplicar operações consistentes é uma característica fundamental do polimorfismo.

Portanto, nesse caso, a função localeCurrency pode ser considerada uma função polimórfica, pois opera em diferentes valores numéricos (preços) de maneira uniforme, fornecendo a conversão correta da moeda com base na língua selecionada.


Top comments (0)