Polimorfizm w C#
1. Wprowadzenie
Polimorfizm to jedna z fundamentalnych cech programowania obiektowego (OOP). Pochodzi od greckiego: poly = wiele, morph = forma, co oznacza wiele form.
W kontekście C# polimorfizm pozwala:
- używać tej samej nazwy metody w różnych klasach,
- wywoływać metody klasy pochodnej poprzez referencję klasy bazowej,
- pisać kod bardziej elastyczny i skalowalny.
Polimorfizm dzieli się głównie na polimorfizm statyczny (kompilacyjny) i polimorfizm dynamiczny (wywołania w czasie działania programu).
2. Polimorfizm statyczny (compile-time)
Polimorfizm statyczny polega na tym, że decyzja, którą metodę wywołać, jest podejmowana w czasie kompilacji.
2.1 Przeciążanie metod (method overloading)
- Ta sama nazwa metody, różne parametry (liczba, typ, kolejność).
Zasady przeciążania metod:
- Różna liczba parametrów,
- Różne typy parametrów,
- Różna kolejność parametrów.
Nie można przeciążać metod tylko przez zmianę typu zwracanego.
2.2 Przeciążanie operatorów (operator overloading)
C# pozwala nadpisywać operatory dla własnych typów klas lub struktur:
3. Polimorfizm dynamiczny (run-time)
Polimorfizm dynamiczny polega na tym, że decyzja, którą metodę wywołać, jest podejmowana w czasie działania programu.
W C# osiąga się go dzięki dziedziczeniu, metodom wirtualnym i nadpisywaniu metod.
3.1 Metody wirtualne i override
virtual– metoda klasy bazowej, którą można nadpisać,override– metoda klasy pochodnej, która nadpisuje metodę bazową.
Pomimo, że zmienne są typu
Zwierze, wywoływana jest metoda klasy pochodnej. To polimorfizm w czasie wykonania.
3.2 Sealed i new
sealed– uniemożliwia dalsze nadpisywanie metod.new– ukrywa metodę klasy bazowej, ale nie nadpisuje jej w sensie polimorfizmu dynamicznego.
Użycie
newpowoduje ukrycie metody, a nie prawdziwe nadpisanie.
3.3 Polimorfizm i kolekcje
Polimorfizm umożliwia tworzenie kolekcji różnych obiektów klas pochodnych, które można traktować jak obiekty klasy bazowej:
4. Podsumowanie rodzajów polimorfizmu
| Typ polimorfizmu | Kiedy decyzja wywołania jest podejmowana | Przykład w C# |
|---|---|---|
| Statyczny (compile-time) | Podczas kompilacji | Przeciążanie metod, operatorów |
| Dynamiczny (run-time) | Podczas działania programu | Metody wirtualne i override |
5. Dobre praktyki polimorfizmu
- Używaj metod wirtualnych i override dla funkcji, które mogą mieć różne zachowania w klasach pochodnych.
- Nie nadużywaj
new– może prowadzić do nieintuicyjnych wyników. - Stosuj polimorfizm w kolekcjach i hierarchiach klas, aby kod był elastyczny i rozszerzalny.
- Polimorfizm statyczny (przeciążanie) – używaj do zwiększenia czytelności i wygody korzystania z klasy.
- W polimorfizmie dynamicznym zwracaj uwagę na bezpieczeństwo typów i unikaj rzutowania, jeśli to możliwe.