C#

Polimorfizm - wielopostaciowość

elektronator

W tym artykule dowiesz się o podstawach polimorfizmu, jak go używać i kiedy.

***

Temat ten jest ściśle związany z dziedziczeniem i bez opanowania tamtego tematu proszę ten artykuł traktować jako ciekawostkę.

Polimorfizm oznacza wielopostaciowość. Termin ten jest związany z programowaniem obiektowym, występującym nie tylko w języku C#, lecz w wielu innych językach i wygląda ono dosyć podobnie.

Poznając polimorfizm najważniejsze jest poznanie kiedy tego używać i podam 2 proste przykłady (mogą się wydać głupie jednak adekwatne i bardzo dydaktyczne)

  1. Gra komputerowa
  2. System logowania

Zacznijmy od gry komputerowej. Tworząc grę RPG mamy do wyboru kilka klasy postaci np. wojownik, mag i złodziej. Każda z nich dziedziczy jakieś zmienne m.in. życie siła_ataku. Dziedziczymy także i metody, jednak istnieje możliwość ustawienia metody tak by wykonywała się ta która jest u potomka. U rodzica wystarczy dać słówko virtual jeśli chcemy by była możliwość wykonania czynności domyślnych o ile w klasie pochodnej nie występuje ta metoda, lub abstract gdy chcemy by w klasie pochodnej musiała występować metoda wraz z ciałem. Taką metodą wirtualną może być metoda Atak, gdzie domyślnie wykonuje się atak pięścią a w klasach pochodnych atak mieczem, wachlarzem itp. Jednak po jakimś czasie chcemy dodać kolejną grywalną postać dajmy na to skrytobójcę, wystarczy że dodamy kolejną klasę, będzie ona dziedziczyć ze wspólnej klasy co 3 pozostałe i wystarczy uzupełnić to co trzeba. Jednak trzeba pamiętać o jednej rzeczy. Typem zmiennej może być ta klasa podstawowa a przypisywanym typem do niej ta klasa pochodna.

Poprzedni przykład może i był trochę trudny do zrozumienia, ale pamiętaj: polimorfizmu używamy do tego by program był łatwiej rozszerzalny.
Tak jak wcześniej podałem przykład z tym skrytobójcą, łatwo było rozszerzyć program? TAK! Przecież potem do metody wysyłamy zmienną do której przypisujemy obiekty klasy pochodnej.

To może teraz pora na przykład z systemem logowania. Załóżmy że tworzymy program do szkoły, gdzie jest system logowania. Mamy takie klasy jak Dyrektor, Nauczyciel Administrator. Program jest skończony, jednak zleceniodawca mówi nam: No trzeba dodać do programu jeszcze konserwatora i chcę żeby to było tak tak i tak". I teraz nie ma problemu by już 3 dni później pokazać poprawiony program. (Nie zastanawiamy się jak to ma wyglądać).

Mam nadzieję że na tych 2 przykładach wyjaśniłem Ci DLACZEGO i PO CO stosować polimorfizm. Nie wyjaśniliśmy jeszcze jak konkretnie. Już pokazuję:
Mamy klasę Figura i klasy pochodne Kwadrat i Kolo (brak polskich znaków). Klasa podstawowa ma metodę abstrakcyjną ObliczPole, a klasa pochodna musi mieć jej implementację.

 
Figura.cs
 
namespace nauka
{
    abstract class Figura
    {
        public abstract void ObliczPole();
    }
}
 
Kwadrat.cs
 
using System;
 
namespace nauka
{
    class Kwadrat : Figura
    {
        private float bok;
 
        public Kwadrat(float bok)
        {
            this.bok = bok;
        }
 
        public override void ObliczPole()
        {
            Console.WriteLine("Pole kwadratu wynosi {0}", bok * bok);
        }
    }
}
 

Wygląda źle? Oczywiście że nie! A teraz mamy do programu dodać nową klasę o nazwie Kolo.

 
Kolo.cs
 
using System;
 
namespace nauka
{
    class Kolo : Figura
    {
        private float r;
        public Kolo(float r)
        {
            this.r = r;
        }
 
        public override void ObliczPole()
        {
            Console.WriteLine("Pole koła wynosi {0}", Math.PI * r * r);
        }
    }
}
 

a jak to wygląda ze strony używania tego wszystkiego?

 
Program.cs
 
namespace nauka
{
    static class Program
    {
        static void Main(string[] args)
        {
            Figura figura = new Kolo(2);
 
            figura.ObliczPole();
 
            figura = new Kwadrat(5);
 
            figura.ObliczPole();
        }
    }
}
 

Kilka uwag na sam koniec:

  • używanie słowa kluczowego var nie będzie współpracowało z polimorfizmem, podobnie słówko dynamic

  • można użyć polimorfizmu nie tylko z klasą abstrakcyjną ale także i interfejsem lub zwykłą klasą.
C#

0 komentarzy