07.1: Dziedziczenie i klasy podstawowe

Cele lekcji

Po zakończeniu tej lekcji…

  • Zrozumiesz, dlaczego warto stosować dziedziczenie.
  • Dowiesz się, jak korzystać z dziedziczenia i klas podstawowych.

 

Właściwości klas zawierają mnóstwo powtórzeń

W projekcie Engine mamy już siedem klas: HealingPotion, Item, Location, Monster, Player, Quest i Weapon.

Niektóre z nich zawierają bardzo podobne właściwości, a inne reprezentują te same składniki. Przykładowo:

  • HealingPotion, Item i Weapon zawierają właściwości ID, Name i NamePlural. Reprezentują one również przedmioty, które gracz może znaleźć podczas gry.
  • Klasy Player i Monster zawierają takie same właściwości ID, CurrentHitPoints, and MaximumHitPoints. Obydwie dotyczą „żywych istot” w grze.

Jeśli w kodzie istnieją klasy odzwierciedlające te same typy elementów i zawierają one podobne właściwości (lub funkcje, ale o tym za chwilę) wskazujące te same składniki, warto zastosować dziedziczenie, czyli inny zakres projektowania obiektowego.

Ustawimy klasę Item jako klasę podstawową względem HealingPotion i Weapon, ponieważ wszystkie te klasy zawierają właściwości znajdujące się w klasie Item.

Następnie utworzymy nową klasę podstawową LivingCreature, która będzie zawierać współdzielone właściwości CurrentHitPoints i MaximumHitPoints należące do klas Monster i Player.

Jak to zrobimy?

 

 

Etap 1: Uruchom aplikację Visual Studio i otwórz swoje rozwiązanie.

 

Etap 2: W projekcie Engine dwukrotnie kliknij klasę HealingPotion. Wiersz 9. zmodyfikuj, aby wyglądał tak:

public class HealingPotion : Item

Dodanie dwukropka i nazwy klasy Item po klasie HealingPotion oznacza, że klasa HealingPotion ma teraz klasę podstawową o nazwie Item. Więc wszystkie publiczne właściwości i metody z klasy Item są teraz automatycznie dostępne w klasie HealingPotion, nawet jeśli usuniemy wiersze dotyczące właściwości ID, Name i NamePlural.

HealingPotion jest teraz klasą podrzędną lub klasa pochodną względem klasy Item. Programiści powszechnie używają tych nazw w odniesieniu do klas dziedziczących informacje z innych klas.

Teraz możemy usunąć właściwości ID, Name i NamePlural z klasy HealingPotion, ponieważ są one już dostępne w klasie podstawowej.

Jedną z najważniejszych korzyści płynących z korzystania z klasy podstawowej jest fakt, że nie powielamy tych samych właściwości ani metod we wszystkich jej klasach podrzędnych. Klasy podrzędne mają dostęp do zmiennych/właściwości/metod/itd. znajdujących się w klasie podstawowej, o ile ich zakresem nie jest private (prywatne). Dowolny element określony jako private jest dostępny tylko w ramach klasy podstawowej.

Więc właściwości ID, Name i NamePlural znajdują się teraz „wewnątrz” klasy HealingPotion, ponieważ są one w klasie podstawowej, a nie prywatnej.

 

Etap 3: Klasę Weapon potraktuj tak samo jak klasę HealingPotion – dodaj klasę podstawową Item i usuń wiersze z trzema właściwościami już znajdującymi w klasie Item.

 

Etap 4: Nie masz jeszcze klasy z właściwościami wspólnymi znajdującymi się w klasach Monster i Player, więc utwórz nową klasę o nazwie LivingCreature z właściwościami typu liczba całkowita dla klas CurrentHitPoints i MaximumHitPoints. Musimy ją też określić jako public. Klasa podstawowa musi być dostępna co najmniej na takim samym poziomie (w kontekście jej zakresu) jak jej klasy podrzędne.

 

Etap 5: Zmodyfikuj klasy Monster i Player, aby ich klasą podstawową była LivingCreature (dodaj średnik i tekst LivingCreature w wierszach rozpoczynających się od public class), i usuń właściwości CurrentHitPoints oraz MaximumHitPoints z tych dwóch klas, ponieważ będą one teraz korzystać z właściwości z klasy podstawowej.

 

Etap 6: W projekcie interfejsu użytkownika wyświetl kod formularza SuperAdventure (prawym przyciskiem myszy kliknij pozycję SuperAdventure.cs). Zauważ, że w wierszach 25, 26-31 właściwości Player CurrentHitPoints i MaximumHitPoints nie są podkreślone na czerwono nawet pomimo usunięcia ich z klasy Player. Jest to spowodowane tym, że klasa odziedziczyła te właściwości ze swojej klasy podstawowej, czyli z LivingCreature.

 

Etap 7: Uruchom program i sprawdź, czy wartość CurrentHitPoints jest nadal poprawnie wyświetlana na ekranie.

 

Podsumowanie

Teraz już wiesz, w jaki sposób i po co tworzy się klasy podstawowe dla klas w programie. Są one nadzwyczaj użyteczne podczas tworzenie dużych aplikacji, gdy chcemy mieć pewność, że podobne klasy zachowują się podobnie.

Klasy podstawowe umożliwiają również udostępnianie funkcji (Lekcja 09), więc nie trzeba wielokrotnie stosować tego samego kodu w różnych miejscach i uważać, aby nie popełnić błędów podczas dublowania opisów klas.

Istnieją pewne zaawansowane warunki określające dostępność elementów z klasy podstawowej w klasach podrzędnych, ale w naszym kursie je pominiemy.

 

Łącza do tej lekcji

Kod źródłowy w serwisie GitHub

Kod źródłowy w serwisie Dropbox

Leave a Reply

Your email address will not be published. Required fields are marked *