Temat: Klasy zagnie d one. Dziedziczenie. Dziedziczenie a
Transkrypt
Temat: Klasy zagnie d one. Dziedziczenie. Dziedziczenie a
Temat: Klasy zagnie d one. Dziedziczenie. Dziedziczenie a hermetyzacja. Polimorfizm i metody wirtualne. 1. Klasy zagnie d one Przykład 1 Klasy zagnie d one class Bank { public class Konto { private double stan; public void UstawStan(double s) { stan = s; } private void f() { Kredyt K = new Kredyt(); K.UstawDlug(1000.0); K.dlug = 500.0; // bład !!! } } // koniec deklaracji klasy Konto private class Kredyt { private double dlug; public void UstawDlug(double d) { dlug = d; } private void g() { Konto K = new Konto(); K.UstawStan(1500.0); K.stan = 1000.0; // bł d !!! } } // koniec deklaracji klasy Kredyt private void h() { Konto Ko=new Konto(); Kredyt Kr=new Kredyt(); } } // koniec deklaracji klasy Bank class Program { static void Main( ) { Bank.Konto Ko=new Bank.Konto(); Bank.Kredyt Kr=new Bank.Kredyt(); // bł d !!! } } • Klasy Kredyt i Konto s dost pne w klasie Bank. • Klasa Kredyt jest dost pna w klasie Konto i odwrotnie. • Klasa Kredyt jest prywatna w klasie Bank i nie jest dost pna na zewn trz klasy Bank • Prawa dost pu do klasy zewn trznej nie s zatem takie same jak dla klasy wewn trznej. Klasa zewn trzna nie mo e by zadeklarowana jako prywatna. • Klasy zagnie d one mog by zadeklarowane jako publiczne albo prywatne. Przykład 2 Klasy zagnie d one class Bank { class Konto { ... } // klasa Konto jest prywatna public Konto OtworzPubliczneKonto( ) // bł d !!! { Konto O = new Konto( ); O.Ustaw( ); return O; } private Konto OtworzPrywatneKonto( ) { Konto O = new Konto( ); O.Ustaw( ); return O; } } • Klasa Konto jest dost pna w metodach OtworzPubliczneKonto i OtworzPrywatneKonto, poniewa obydwie metody nale do klasy Bank. Jednak metoda OtworzPubliczneKonto nie skompiluje si , poniewa jest to metoda publiczna, a powinna by prywatna, skoro działa na prywatnej klasie Konto. 2. Dziedziczenie • Klasa potomna dziedziczy z klasy bazowej: - wszystkie dane składowe, - wszystkie metody oprócz konstruktorów i destruktorów. • Nie mo na dziedziczy z prywatnej wewn trznej klasy. Przykład 3 Prosta hierarchia klas class Pojazd{ double maks_predkosc; public void Ruch( ) { ………… } } class Samochod:Pojazd{ double moc_silnika; public void Jedz() { ............ } } Samochod S=new Samochod(); Pojazd Samochód Przykład 4 Prosta hierarchia klas class Przyklad { private class WewnetrznaBazowa{ } public class WewnetrznaPotomna:WewnetrznaBazowa{ } // bład !!! } Dost p do elementów klasy bazowej • Elementy klasy potomnej maj dost p do elementów typu protected i public z klasy bazowej. • Publiczne składniki klasy bazowej s potomnej. publiczne równie w klasie • Prywatne składniki klasy bazowej s niedost pne w klasie potomnej. • Elementy typu protected s dost pne wył cznie w klasie, w której s definiowane oraz we wszystkich klasach potomnych tej klasy. • Elementy typu proteced nie s dost pne w klasach, które nie s potomne w stosunku do klasy, w której te elementy s definiowane. • Elementy typu protected w danej klasie bazowej s protected w klasie potomnej. Przykład 5 Dost p do elementów klasy bazowej class Bazowa{ protected string name; public int a; int b; } class Potomna: Bazowa{ public void f() { Console.WriteLine(name); a++ ; b++; // bł d !!! } } class PotomnaPotomnej: Potomna { protected void g( ) { Console.WriteLine(name); a++ ; b++; // bł d !!! } } class Program{ static void Main() { PotomnaPotomnej D=new PotomnaPotomnej(); D.a=2; D.b=3; // bł d !!! równie typu D.name="Test"; // bł d !!! D.f(); D.g();// bł d !!! } } • Je eli klasa bazowa nie ma jawnego konstruktora, a klasa potomna ma jawny konstruktor, to na rzecz instancji klasy potomnej najpierw wywoła si konstruktor domy lny klasy bazowej, a potem konstruktor klasy potomnej. • Je eli klasy: bazowa i potomna nie maja jawnego konstruktora, to kompilator wygeneruje konstruktory domy lne dla tych klas i przy tworzeniu instancji klasy potomnej najpierw wywoła konstruktor domy lny klasy bazowej a potem konstruktor domy lny klasy potomnej. • Je eli klasa bazowa ma tylko jawny konstruktor, który nie jest domy lny, to w konstruktorze klasy potomnej nale y wywoła konstruktor klasy bazowej, stosuj c słowo base. Przykład 6 Wywołanie konstruktorów klasy bazowej class Token{ protected Token(string name) { ... } } class CommentToken : Token{ public CommentToken(string name) { ... } // bł d !!! } //-----------------------------------------------------class Token{ protected Token() { } public Token(string name) { } } class CommentToken : Token{ public CommentToken(string name) { } } //-----------------------------------------------------class Token{ public Token(string name) { } } class CommentToken : Token{ public CommentToken(string name) : base(name) { } } Przykład 7 Wywołanie konstruktorów klasy bazowej class Bazowa{ private Bazowa() { ... } } class Potomna : Bazowa{ public Potomna() { ... } // bł d !!! } • Mo na u y słowa base tak e, aby zaznaczy odniesienie do tych samych identyfikatorów, które zostały zadeklarowane w klasie bazowej i potomnej. Przykład 8 Odwołanie do składników klasy bazowej o tej samej nazwie co w klasie potomnej class Token{ protected string name; protected void f() {……} } class CommentToken: Token{ public void Method(string name) { base.name = name; base.f(); } } 3. Metody wirtualne • Metoda wirtualna to metoda, która mo e by nadpisana (przedefiniowana) w klasie potomnej i wywołana polimorficznie, tj. inaczej na rzecz instancji klasy bazowej i inaczej na rzecz instancji klasy potomnej. • Aby zadeklarowa metod nagłówku tej metody. wirtualn trzeba wpisa słowo virtual w • Aby nadpisa metod wirtualn w klasie potomnej nale y wpisa słowo override w deklaracji metody przedefiniowuj cej. Przykład 9 Metoda wirtualna i jej polimorficzne wywołanie class Instrument { public virtual void Play() { Console.WriteLine("Jakis instrument gra ..."); } } class Piano : Instrument { public override void Play() { Console.WriteLine("Plim Plim Plim ...."); } } class Gitar : Instrument { public override void Play() { Console.WriteLine("Tran Tran Tran ...."); } } class Program { static void Concert(Instrument[] T) { for (int i=0;i<T.Length;i++) T[i].Play(); } static void Main() { Piano P = new Piano(); Gitar G = new Gitar(); Instrument[] T = new Instrument[2]; T[0] = P; T[1] = G; Concert(T);//polimorficzne wywołanie metody Play } } Wynik: Plim Plim Plim .... Tran Tran Tran .... • Metoda wirtualna nie mo e by zadeklarowana jako statyczna ani prywatna. Przykład 10 Przedefiniowywanie metod class Token { protected virtual string Name() { ... } } class CommentToken : Token { public override void Name(int i) { ... } // bł d !!! } Przykład 11 Przedefiniowywanie metod class Token { public virtual string Name() { ... } } class CommentToken : Token { public override string Name() { ... } } class OneLineCommentToken : CommentToken { public override string Name() { ... } } Przykład 12 Przedefiniowywanie metod class Token { public virtual string Name() { ... } } class CommentToken : Token { public virtual override string Name() { ... }//bł d !!! } • Tylko metody wirtualne mog mie swoje przedefiniowane odpowiedniki w klasach potomnych (metody typu override). • Metody zarówno wirtualne jak i niewirtualne mog by ukryte, czyli mog by zdefiniowane na nowo w klasach potomnych jako metody typu new. • Metoda mo e by jednocze nie wirtualna i typu new. Metoda taka zast puje swój odpowiednik z klasy bazowej i mo e by polimorficznie przedefiniowana w klasie potomnej. • Je eli chcemy ukry metod wirtualn z klasy bazowej, czyli nie chcemy tworzy przedefiniowania metody wirtualnej, tylko zdefiniowa zupełnie now metod , to musimy wpisa new w nagłówku tej metody. Przykład 13 Ukrywanie metod klasy bazowej class Token { public virtual int LineNumber() { ... } } class CommentToken : Token { public int LineNumber() { ... } // Ostrze enie!!! } • Słowo new jest potrzebne tylko wtedy, gdy chcemy ukry metod o identycznej sygnaturze z klasy bazowej. Przykład 14 Ukrywanie metod klasy bazowej class Token { public int LineNumber(short s) { ... } } class CommentToken : Token { new public int LineNumber(int i) { ... }//Ostrze enie!!! } Przykład 15 Ukrywanie metod klasy bazowej class A { public virtual void M() { Console.Write("A"); } } class B : A { public override void M() { Console.Write("B"); } } class C : B { new public virtual void M() { Console.Write("C"); } } class D : C { public override void M() { Console.Write("D"); } static void Main() { D d = new D(); C c = d; B b = c; A a = b; d.M(); c.M(); b.M(); a.M(); } } Co sie uka e na ekranie w wyniku wykonania powy szego programu? Odpowied : DDBB Przykład 18 Przedefiniowywanie metod class Base { public void Alpha( ) { ... } public virtual void Beta( ) { ... } public virtual void Gamma(int i) { ... } public virtual void Delta( ) { ... } private virtual void Epsilon( ) { ... } // bł d !!! } class Derived: Base { public override void Alpha( ) { ... }// bł d !!! protected override void Beta( ) { ... } // bł d !!! public override void Gamma(double d){ ... }// bł d !!! public override int Delta( ) { ... } // bł d !!! }