Temat: Klasy typu sealed. Klasy abstrakcyjne. Deklaracja i implementacja interfejsu. Typ Object i operatory is oraz as. Czas ycia obiektu. Destruktory. 1. Klasa typu sealed Przykład 1 Klasa typu sealed Klasa typu sealed to klasa z której nie mona dziedziczy. Wiele klas w.net Framework to klasy, z których nie mona dziedziczy, np. klasa String. Aby zaznaczy, e klasa jest typu sealed, naley w jej nagłówku (na pocztku) wpisa słowo sealed. sealed class Standard class NowyStandard:Standard // błd!!!
2. Deklaracja i implementacja interfejsu Interfejs jest spisem treci klasy. Zwiera nagłówki metod klasy bez ich kodów. Interfejsy to typy pozwalajce na definiowanie wielu klas spełniajcych podobne funkcje. Wykorzystanie interfejsu jest realizowane przez jego implementacj w klasie. Jeeli klasa implementuje interfejs, to musi zawiera kody wszystkich metod z tego interfejsu. Jest zalecane, aby nazwy interfejsu danej klasy były konstruowane z litery I oraz nazwy klasy, która ten interfejs implementuje, np. interfejs IToken implementuje klasa Token.
Przykład 2 Deklaracja interfejsu interface ISamochod public void Jedz( ); // błd!!! void Stop( ); void Skrecaj( )... // błd!!! Metody z interfejsu oraz ich odpowiedniki w implementacji musz by identyczne, tj. ten sam typ zwracanej wartoci, nazwa, lista parametrów. Wszystkie metody, które s umieszczone w interfejsie danej klasy s domylnie publiczne.
Przykład 3 Klasa implementujca interfejs interface ISamochod void Jedz(); void Stop(); void Skrecaj(); class Samochod: ISamochod int predkosc; public Samochod(int v) if (v > 0) predkosc = v;else predkosc = 10; public void Jedz() Console.WriteLine("Jad, jad... z predkoscia 0",predkosc); public void Stop() Console.WriteLine("Stoj, nie jad!!!"); predkosc = 0; public void Skrecaj() Console.WriteLine("Skrcam, ju nie jad prosto."); class Program static void Main() Samochod S = new Samochod(40); S.Jedz(); S.Skrecaj(); S.Stop();
W jzyku C# nie ma wielodziedziczenia, ale jedna klasa moe implementowa wiele interfejsów. Jeden interfejs moe dziedziczy z wielu innych interfejsów. Przykład 4 Klasa implementujca wiele interfejsów interface IToken... interface IVisitable... interface IVisitableToken: IVisitable, IToken... class Token: IVisitableToken... Moe si zdarzy, e dwa interfejsy zawieraj metod o tej samej sygnaturze (tj. o tej samej nazwie, typie zwracanej wartoci, typach i iloci zwracanych parametrów). Jeeli w klasie implementujcej obydwa te interfejsy zdefiniujemy t metod raz, to bdziemy mogli wykorzysta t jedn wersj metody. Moemy równie uy jawnej definicji metody w klasie implementujcej interfejs poprzedzajc jej nazw nazw interfejsu.
Dziki jawnej definicji moemy zdefiniowa dwie wersje metody ujtej w dwóch rónych interfejsach. Interfejs jest typem, wic mona tworzy zmienne tego typu, ale nie jest klas, wic nie mona tworzy obiektów typu interfejsu. Przykład 5 Jawna implementacja metod interfejsu interface ISamochod void Jedz(); void Stop(); void GraMuzyka(); interface IRower void Jedz(); void Stop(); class Pojazd: ISamochod, IRower int predkosc; public Pojazd(int v) if (v > 0) predkosc = v; else predkosc = 10; void ISamochod.Jedz()// przy implementacji // jawnej nie wpisujemy // modyfikatora public Console.WriteLine("Jad, jad samochodem... z predkoscia 0",predkosc); void IRower.Jedz() Console.WriteLine("Jad, jad rowerem... z predkoscia 0", predkosc); public void Stop() Console.WriteLine("Stoj, nie jad!!!");
predkosc = 0; public void GraMuzyka() Console.WriteLine("Gra muzyka..."); class Program static void Main() Pojazd P = new Pojazd(40); ISamochod S = P;// definicja zmiennej // interfejsu ISamochod. // Obiekt P implementuje // interfejs ISamochod S.Jedz(); S.GraMuzyka(); S.Stop(); IRower R = P; R.Jedz(); R.GraMuzyka();// błd!!! R.Stop();
3. Klasy abstrakcyjne Klasa abstrakcyjna, to taka niedokoczona klasa, która moe by podstaw do budowy bardziej szczegółowych klas. Mona deklarowa metody abstrakcyjne w klasach abstrakcyjnych. Metody abstrakcyjne to metody bez kodu. Klasy, które nie s abstrakcyjne nie mog zawiera metod abstrakcyjnych. Klasy abstrakcyjne, w odrónieniu od interfejsów, mog zawiera dane i metody.
Przykład 6 Porównanie klas abstrakcyjnych i interfejsów interface IToken string Name1(); abstract class Token int x; public virtual string Name2()... class CommentToken : Token, IToken public string Name1()... public override string Name2()...
Metody abstrakcyjne s wirtualne. Metody abstrakcyjne mog by przedefiniowywane w nastpnych klasach potomnych. Metody abstrakcyjne mog przedefiniowywa metody wirtualne klas bazowych. Przykład 7 Implementacja metod abstrakcyjnych abstract class Token public virtual abstract string Name()...// błd!!! class CommentToken : Token public override string Name()...
class Token public virtual string Name()... abstract class Force : Token public abstract override string Name(); 4. Typ Object i operator is oraz as
Przykład 8 Operator is Hierarchia: Bazowa Potomna Kolejna Bazowa B=new Bazowa(); Potomna P=B; // błd kompilacji!!! Kolejna K=P; // błd kompilacji!!! Potomna P=(Potomna)B; // błd wykonania!!! Kolejna K=(Kolejna)P; // błd wykonania!!! Potomna P1=new Potomna(); Bazowa B1=P1; // konwersja niejawna if (B1 is Kolejna) Console.WriteLine("B1-Kolejna"); if (B1 is Potomna) Console.WriteLine("B1-Potomna"); if (B1 is Bazowa) Console.WriteLine("B1 -Bazowa");
Operator as jest uywany jako zabezpieczenie przed błdnym podstawieniem pod dan referencj obiektu spoza hierarchii klas albo obiektu klasy bazowej pod referencj klasy potomnej. Jeeli podstawienia obiektu pod referencj jest moliwe to zostaje zrealizowane poprawnie, a gdy konwersja nie jest moliwa, to referencja przyjmuje warto null. Przykład 9 Operator as Bazowa B = new Bazowa(); Potomna P = B as Potomna; Kolejna K = P as Kolejna; if (P == null) Console.WriteLine("P nie jest obiektem klasy Potomna"); if (K == null) Console.WriteLine("K nie jest obiektem klasy Kolejna"); Potomna P1 = new Potomna(); B = P1 as Potomna; if (B!= null) Console.WriteLine("B jest obiektem klasy Potomna");
5. Czas ycia obiektu Niszczenie obiektu naley wykona w dwóch krokach: I krok: Deinicjalizacji obiektu operacje na obiekcie, które s niezbdne w swoim wykonaniu zanim obiekt zniknie z pamici. Deinicjalizacja zajmuje sie specjalna funkcja destruktor. II krok: Dealokacja obiektu pami zajmowana przez obiekt wraca do zasobów. Dealokacja w jzyku C# odbywa si w sposób automatyczny i realizowana jest przez Garbage Collection (tzw. odmiecacz pamici) Tworzenie obiektu jest deterministyczne, ale niszczenie ju takie nie jest. Programista nie moe (a raczej nie musi!!!) kontrolowa, kiedy dokładnie obiekt zostanie zniszczony, bo robi to za niego Garbage Collection.
Mona wywoła jawnie Garbage Collection, ale nie jest to zalecane. Kiedy Garbage Collection niszczy obiekt, sprawdza, czy klasa niszczonego obiektu ma destruktor. Jeeli tak, to destruktor jest automatycznie wywoływany przed dealokacj pamici obiektu.
Jeeli w klasie znajduj sie zasoby pamici (dane typu referencyjnego, wymagajce przydziału pamici tablice, kolekcje, obiekty innych klas), to nie zwalniamy ich w destruktorze, poniewa zajmuje sie tym Garbage Collection. Jeeli w klasie znajduje sie destruktor, to na pewno zostanie on wywołany zanim Garbage Collection zdealokuje obiekt. Garbage Collection gwarantuje równie, e jeeli obiekt zawiera referencje do zasobów pamici jeszcze nie zwolnionych, to najpierw zdealokuje ten wewntrzny zasób. Przykład 10 Destruktor klasy i Garbage Collection class Tablica int[] Tab; int ilosc; int max; public Tablica(int m) if (m > 0)
max = m; Tab = new int[max]; ilosc = 0; else max = 0; ilosc = 0; Tab = null; ; public void Wczytaj(int ile) if (ilosc <= ilosc + ile) for (int i = 0; i < ilosc + ile; i++) Tab[i] = int.parse(console.readline()); ilosc += ile; ~Tablica() for (int i = 0; i < ilosc; i++) Console.Write("0 ", Tab[i]); class Program static void Main() Tablica T = new Tablica(5); Tablica G; T.Wczytaj(3); T = null; // Garbage Collection moe // ju zwolni pamie dla obiektu T for (int i = 0; i < 1000; i++) G = new Tablica(100); // w trakcie wykonania ptli kurcz si zasoby i // Garbage Collection zwolni pamie obiektu T, // wczeniej jednak wywoła si destruktor klasy // Tablica i zajdzie zwolnienie pamici dla tablicy // Tab w obiekcie T Skoro destruktory nie musz zwalnia zasobów wewntrznych obiektu, to przydaj si duo rzadziej ni w jzyku C++.
Klasa powinna mie destruktor tylko wtedy, gdy chcemy zdenicjalizowa ( wyczyci ) obiekt.