public static void Przesłanianie() // Nazewnictwo: nadpisanie/przesłanianie metody { /* Metoda która z założenia służy do tego, aby została przeszłonięta przez inna implementacje nazywamy metodą 'wirtualną'. * Więcej o metodzie wirtualnej i override w klasie 'Ssak' i 'Kon'. * Różnica pomiedzy 'Przesłonięciem'(ang. overriding) a 'Ukrywaniem' * Przesłonięcie metody polega na tym aby metoda wykonywała te same zadanie w sposób zależny od danej klasy. * Ukrycie metody - metody mogą wykonywać dwa całkowicie różne zadania. Ukrycie metody jest często błędem. */ Ssak ssak = new Ssak(); Kon kon = new Kon(); Zebra zebra = new Zebra(); Delfin defin = new Delfin(); /* Metoda wirtalna a 'polimorfizm' * Przy pomocy metod wirtualnych można wywoływać różne wersje tej samej metody w zależności od faktycznego typu obiektu przekazanego do zmiennej. * Typ obiektu może być tworzony dynamicznie, w trakcie działania programu. */ // W klasie Ssak metoda Mowa() jest virtualna. Klasa Kon ją nadpisuje (override). ssak = kon; ssak.Mowa(); // Wykona się metoda z klasy Kon. ssak = zebra; ssak.Mowa(); // Wykona się metoda z klasy Zebra. // defin nie implementuje metody Mowa() ssak = defin; ssak.Mowa(); // Wykona się metoda z klasy Ssak. /*Note: Gdyby metoda Mowa() była ukryta a nie nadpisana to wykonałaby się metoda z klasy Ssak. * Jednak tak nie jest i na tym właśnie polaga polimorfizm (wiele form). */ }
public static void Polimorfizm(int index) { Ssak ssak; switch (index) { case 1: ssak = new Kon(); break; case 2: ssak = new Zebra(); break; case 3: ssak = new Delfin(); break; default: ssak = new Ssak(); break; } ssak.Mowa(); // Na podstawie podanego parametru mogę utworzyć różny obiek i za pomocą jednej instrukcji wykonać metodę zaimplementowaną w sposób zależny od klasy. }
public static void Init() { Ssak mojSsak = new Ssak(); Kon mojKon = new Kon(); mojKon.ZaluzSiodlo(); mojSsak = mojKon; mojSsak.ZaluzSiodlo(); // błąd. Odwołujac się do obiektu klasy Kon za pomocą zmiennej typu 'Ssak' możemy korzystać tylko z metod i właściwości zdefiniowanych w klasie 'Ssak' // Metoda ZaluzSiodlo() (ang. put saddle) jest tylko w klasie Kon. Ssak jakisSsak = new Ssak(); // Kon jakisKon = jakisSsak; // błąd. Nie można przypisać obiektu klasy 'Ssak' to zmiennej typu 'Kon'. Klasa 'Kon' "rozszerza" klase 'Ssak' i zawiera wiecej pól i metod, dlatego jest to niemożliwe. // Możliwe jest przypisanie pod warunkiem, że obiekt klasy 'Ssak' tak naprawde jest Koniem. Można to sprawdzić za pomocą operatorów 'as', 'is' lub rzutowania przykład poniżej. Kon konik = new Kon(); Ssak ssak = konik; Kon konPonownie; if (ssak is Kon) { konPonownie = (Kon)ssak; } Delfin delfin = new Delfin(); ssak = delfin; konPonownie = ssak as Kon; // Oprator as zwróci 'null', gdyż obiekt 'ssak' jest rownież obiektem klasy 'Delfin' a nie 'Kon'. }
static void Main(string[] args) { Gad gad = new Gad(true, "gad", "muchy", "afryka"); Ssak ssa = new Ssak("dzungla", "ssak", "weze", "ameryka poludniowa"); Ptak pta = new Ptak(2.0, 15.12, "ptak", "ryby", "wyspy zp"); Opiekun op1 = new Opiekun("dawid", "kopacz"); Opiekun op2 = new Opiekun("marcel", "widczynski"); Dyrekcja dyr = new Dyrekcja(); dyr.Zatrudnij("dawid", "koparski"); dyr.Zatrudnij("marcel", "widczynski"); dyr.WypiszInfo(); Console.WriteLine(); dyr.BudujKlatke(14, true, "dawid", "koparski"); dyr.PowiekszKlatke(20, 0); dyr.DodajZwierze(gad, 0); dyr.DodajZwierze(ssa, 0); dyr.BudujKlatke(45, false, "marcel", "widczynski"); dyr.DodajZwierze(pta, 1); dyr.BudujKlatke(55, true, "dawid", "koparski"); dyr.DodajZwierze(gad, 2); dyr.DodajZwierze(ssa, 2); dyr.WypiszInfo(); Console.WriteLine(); dyr.UsunOpiekuna("dawid", "koparski"); dyr.WypiszInfo(); Console.ReadKey(); }
// Ważną zaletą Dziedziczenia jest to, że do tej metody mogę przekazać każdy obiekt klasy dziedziczącej po klase bazowej. public static void Konwersja(Ssak ssak) { Kon mojKon = ssak as Kon; // Wiecej na temat 'as' w rozdział 8 Wartości i Referecje - SaveCasting if (mojKon != null) { mojKon.ZaluzSiodlo(); } }