Polimorfizm

Frontend SELF PL
Poziom 40 , Lekcja 3
Dostępny

10.1 Podstawy polimorfizmu

Polimorfizm to jedna z kluczowych koncepcji w programowaniu obiektowym (OOP). W ogólnym sensie, polimorfizm umożliwia obiektom różnych klas przetwarzanie danych za pomocą tego samego interfejsu. W kontekście JavaScript oznacza to, że różne obiekty mogą mieć metody o tych samych nazwach, a te metody mogą być wywoływane na obiektach bez znajomości ich konkretnych typów.

Typy polimorfizmu

W JavaScript główne typy polimorfizmu to:

1. Polimorfizm ad-hoc (ad-hoc polymorphism):

  • Polimorfizm metod, wywołanie metod o tej samej nazwie dla obiektów różnych typów
  • Przykłady obejmują przeciążanie funkcji i operatorów (co nie jest bezpośrednio obsługiwane w JavaScript, ale może być symulowane)

2. Polimorfizm przez podtypy (Subtype polymorphism):

  • Polimorfizm podtypów lub inkluzji, kiedy obiekty różnych klas, dziedziczących z tej samej klasy bazowej, mogą być traktowane jako obiekty klasy bazowej
  • To podstawowy typ polimorfizmu, realizowany przez dziedziczenie i interfejsy

Korzyści z polimorfizmu:

  1. Uproszczenie kodu: polimorfizm pozwala pisać bardziej elastyczny i ogólny kod, który może działać z różnymi typami obiektów, nie znając ich konkretnych typów.
  2. Rozszerzalność: polimorfizm ułatwia dodawanie nowych typów i zachowań do systemu bez konieczności zmiany istniejącego kodu.
  3. Wsparcie: polimorfizm sprzyja lepszemu podziałowi obowiązków i zwiększa czytelność oraz konserwowalność kodu.

10.2 Przykłady polimorfizmu w JavaScript

Polimorfizm przez podtypy dzięki dziedziczeniu

Przykład 1: Przetwarzanie różnych typów obiektów za pomocą jednego interfejsu

W tym przykładzie funkcja playWithAnimal przyjmuje obiekt typu Animal i wywołuje metodę makeSound. Obiekty Dog i Cat, które dziedziczą po Animal, nadpisują metodę makeSound, dzięki czemu wywołanie tej metody na każdym obiekcie daje różne wyniki.

JavaScript
    
      class Animal {
        makeSound() {
          console.log('Some generic sound');
        }
      }

      class Dog extends Animal {
        makeSound() {
          console.log('Woof!');
        }
      }

      class Cat extends Animal {
        makeSound() {
          console.log('Meow!');
        }
      }

      function playWithAnimal(animal) {
        animal.makeSound();
      }

      const dog = new Dog();
      const cat = new Cat();

      playWithAnimal(dog); // Wyświetli: Woof!
      playWithAnimal(cat); // Wyświetli: Meow!
    
  

10.3 Polimorfizm przez interfejsy (Duck Typing)

W JavaScript nie ma wbudowanej obsługi interfejsów, jak w innych językach, takich jak TypeScript czy Java. Zamiast tego stosuje się podejście, zwane "Duck Typing". Oznacza to, że obiekt uznaje się za zgodny z interfejsem, jeśli ma wymagane metody i właściwości, niezależnie od jego konkretnego typu czy dziedziczenia.

Ważne!

Zasada kaczki (duck): jeśli coś wygląda jak kaczka, pływa jak kaczka i kwacze jak kaczka, to jest to najprawdopodobniej kaczka.

Przykład 2: Zastosowanie Duck Typing

W tym przykładzie funkcja takeOff przyjmuje dowolny obiekt, który ma metodę fly. Obiekty Bird i Airplane implementują metodę fly, dzięki czemu można je przekazać do takeOff.

JavaScript
    
      class Bird {
        fly() {
          console.log('Flying...');
        }
      }

      class Airplane {
        fly() {
          console.log('Jet engine roaring...');
        }
      }

      function takeOff(flyingObject) {
        flyingObject.fly();
      }

      const bird = new Bird();
      const airplane = new Airplane();

      takeOff(bird);      // Wyświetli: Flying...
      takeOff(airplane);  // Wyświetli: Jet engine roaring...
    
  

10.4 Polimorfizm przez funkcje

W JavaScript funkcje są obiektami pierwszej klasy, można je przekazywać i używać do realizacji polimorficznego zachowania.

Przykład 3: Polimorfizm przez funkcje

W tym przykładzie funkcja greet przyjmuje inną funkcję jako argument i ją wywołuje. Dzięki temu można używać różnych funkcji do wykonania różnych działań.

JavaScript
    
      function greetMorning() {
        console.log('Good morning!');
      }

      function greetEvening() {
        console.log('Good evening!');
      }

      function greet(greetingFunction) {
        greetingFunction();
      }

      greet(greetMorning); // Wyświetli: Good morning!
      greet(greetEvening); // Wyświetli: Good evening!
    
  

10.5 Polimorfizm przez przeciążenie metody (Symulacja)

JavaScript nie obsługuje bezpośredniego przeciążenia metod, jak niektóre inne języki programowania. Jednak można zasymulować przeciążenie metod za pomocą argumentów funkcji i ich typów.

Przykład 4: Symulacja przeciążenia metody

W tym przykładzie metoda add przyjmuje dwa argumenty i wykonuje różne działania w zależności od ich typów. Jeśli argumenty to liczby, metoda je dodaje. Jeśli argumenty to tablice, metoda je scala.

JavaScript
    
      class Calculator {
        add(a, b) {
          if (typeof a === 'number' && typeof b === 'number') {
            return a + b;
          } else if (Array.isArray(a) && Array.isArray(b)) {
            return a.concat(b);
          } else {
            throw new Error('Invalid arguments');
          }
        }
      }

      const calc = new Calculator();
      console.log(calc.add(1, 2));           // Wyświetli: 3
      console.log(calc.add([1, 2], [3, 4])); // Wyświetli: [1, 2, 3, 4]
    
  
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION