1 / 47

RP3/predavanje04

RP3/predavanje04. Strukture Delegati Događaji Sučelja. Strukture. Za razliku od klase koja je referentni tip, struktura je vrijednosni tip. Ne podržava nasljeđivanje. Varijable članice se ne mogu inicijalizirati unutar strukture. Struktura može sadržavati sve članove kao i klasa osim:

cliff
Télécharger la présentation

RP3/predavanje04

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. RP3/predavanje04 • Strukture • Delegati • Događaji • Sučelja ---------- Računarski praktikum 3 ---------- Maja Starčević

  2. Strukture Za razliku od klase koja je referentni tip, struktura je vrijednosni tip. Ne podržava nasljeđivanje. Varijable članice se ne mogu inicijalizirati unutar strukture. Struktura može sadržavati sve članove kao i klasa osim: • konstruktora bez parametara • finalizatora • virtualnih (i apstraktnih) članova Napomena: konstruktor bez parametara je implicitno definiran i ne može se redefinirati. Dakle, nije moguće spriječiti instanciranje strukture tako da se svi konstruktori učine privatnima (kao kod klasa). -------Računarski praktikum 3-------

  3. Strukture Struktura se općenito definira na sljedeći način: [attributi] [modifikatori] struct identifikator [:sučelja] { tijelo strukture }[;] -------Računarski praktikum 3-------

  4. Konstruktor strukture Implicitno je definiran konstruktor koji ne prima parametre i koji se ne može redefinirati. Pri definiciji konstruktora mora se eksplicitno dodijeliti vrijednost svakoj varijabli. U strukturi se varijable članice ne mogu inicijalizirati pri deklaraciji. public struct Point { public int x,y; public Point (int x, int y) { this.x=x; this.y=y;} } -------Računarski praktikum 3-------

  5. Konstruktor strukture Primjer pogrešno definirane strukture: public struct Point { public int x=0; // nedozvoljeno, inicijalizacija pri deklaraciji public int y; public Point( ) { } // konstruktor bez parametara se ne može definirati (definiran je implicitno) public Point(int x) { this.x=x; // greška, unutar konstruktora potrebno je inicijalizirati sve varijable } } -------Računarski praktikum 3-------

  6. Strukture i nasljeđivanje Strukture ne podržavaju nasljeđivanje. Drugim riječima, struktura se ne može izvesti ni iz klase ni iz druge strukture. Može samo naslijediti jedno ili više sučelja. Dakle, struktura ne može biti apstraktna. Struktura je uvijek implicitno zaštićena (greška je eksplicitno navesti modifikator sealed). U strukturi dakle ne nalazimo apstraktne i virtualne metode, dok se mogu nadjačavati samo metode definirane u klasi object koju struktura implicitno nasljeđuje. -------Računarski praktikum 3-------

  7. Delegati delegate int RacunskaOperacija( int x ); class Test { static void Main() { RacunskaOperacija r = Kvadriranje; // ili ….. RacunskaOperacija r = new RacunskaOperacija(Kvadriranje); Console.WriteLine( r(3) ); } static int Kvadriranje (int x) { return x*x; } } Deklaracija tipa delegata Kreiranje instance delegata Metoda koja odgovara tipu delegata Računarski praktikum 3

  8. Delegati Primjer: parametar funkcije je tipa delegat. delegate int RacunskaOperacija( int x ); class Program { public static int Racunaj(int broj, RacunskaOperacija operacija) { return operacija(broj); } static void Main(string[] args) { Console.WriteLine(Racunaj(3, Kvadriranje)); } static int Kvadriranje(int x) { return (x * x); } static int Kubiranje (int x) { return (x*x*x); } } Računarski praktikum 3

  9. Delegati Svi delegati su višeodredišni, tj. instance delegata mogu referirati na više ciljanih metoda. To se postiže upotrebom operatora +=. RacunskaOperacija r = Kvadriranje; r += Kubiranje; Pozivanjem instance delegata, pozvat će se sve metode koje su joj dodijeljene i to onim redoslijedom kojim su dodijeljene. Računarski praktikum 3

  10. Delegati delegate int RacunskaOperacija (int x); class Program { static void Main(string[] args) { RacunskaOperacija r = Kvadriranje; r += Kubiranje; Console.WriteLine( r(3) ); } static int Kvadriranje(int x) { return (x * x); } static int Kubiranje(int x) { return (x * x * x ); } } Output: 27 Računarski praktikum 3

  11. Delegati delegate void RacunskaOperacija (int x); class Program { static void Main(string[] args) { RacunskaOperacija r = Kvadriranje; r += Kubiranje; r(3); } static void Kvadriranje(int x) { Console.WriteLine (x * x); } static void Kubiranje(int x) { Console.WriteLine (x * x * x ); } } Output: 9 27 Računarski praktikum 3

  12. Delegati Delegat može sadržavati parametre generičkog tipa. class Program { public delegate T RacunskaOperacija<T> (T arg); static double Kvadriranje(double x) { return x * x; } static void Main(string[] args) { RacunskaOperacija<double> r=Kvadriranje; Console.WriteLine(r(2.5)); } } Računarski praktikum 3

  13. Delegati Delegati su inkompatibilni, čak i ako imaju isti potpis. delegate void D1( ); delegate void D2( ); D1 d1=Metoda1; D2 d2=d1; // greška Instance delegata su jednake ako imaju iste ciljnemetode. delegate void D( ); D d1=Metoda1; D d2=Metoda1; Console.WriteLine(d1==d2); //True Računarski praktikum 3

  14. Delegati public delegate void NekiDelegat(); public class Program { public static void Metoda1( ) { Console.WriteLine("Metoda1"); } public static void Metoda2( ) { Console.WriteLine("Metoda2"); } public static void Metoda3( ) { Console.WriteLine("Metoda3"); } public static void Metoda4( ) { Console.WriteLine("Metoda4"); } Računarski praktikum 3

  15. Delegati static void Main(string[] args) { NekiDelegat d = Metoda1; d += Metoda2; d += Metoda3; d += Metoda3; d += Metoda2; d += Metoda3; d -= Metoda3; d += Metoda4; d += Metoda2; d += Metoda4; d -= Metoda2; d( ); } } Računarski praktikum 3

  16. Delegati static void Main(string[] args) { NekiDelegat d = Metoda1; d += Metoda2; d += Metoda3; d += Metoda3; d += Metoda2; d += Metoda3; d -= Metoda3; d += Metoda4; d += Metoda2; d += Metoda4; d -= Metoda2; d( ); } } Output: Metoda1 Metoda2 Metoda3 Metoda3 Metoda2 Metoda4 Metoda4 Računarski praktikum 3

  17. Događaji Događaji omogućavaju da objekt koji obavještava o nekoj promjeni do koje je došlo, ne mora znati ništa o objektima koje obavještava, tj. ne treba imati referencu na njih. Slušatelji se mogu po potrebi prijavljivati i odjavljivati. Događaj je omotač oko delegata koji sprječava sukobljavanje slušatelja. Računarski praktikum 3

  18. Događaji Izvan objekta izvjestitelja prijavljivanje metoda za događaj može se vršiti samo pomoću operatora +=. Ako ispustimo ključnu riječ event, program i dalje daje isti rezultat, ali u tom slučaju neki od slušatelja mogu ometati druge na način da: • u potpunosti zamijene sve ostale slušatelje koji su se prethodno prijavili za obrađivanje događaja • izbrišu sve prijavljene slušatelje • izvještavaju druge slušatelje o događaju Računarski praktikum 3

  19. Događaji Zadatak: pronađite greške u kodu. public delegate void NekiDelegat(); public class Test { public NekiDelegat d; public event NekiDelegat e; public void f( ) { Program p = new Program( ); p.test( ); d( ); e( ); } } public class Program { public void test() { Console.WriteLine("test"); } static void Main(string[ ] args) { Program p = new Program( ); Test t = new Test( ); t.d = p.test; t.e = p.test; t.d( ); t.e( ); } } Računarski praktikum 3

  20. Događaji public delegate void NekiDelegat(); public class Test { public NekiDelegat d; public event NekiDelegat e; public void f( ) { Program p = new Program( ); p.test( ); d( ); e( ); } } public class Program { public void test() { Console.WriteLine("test"); } static void Main(string[ ] args) { Program p = new Program( ); Test t = new Test(); t.d = p.test; // u redu je i….. t.d += p.test; t.e = p.test; // greška ( t.e += p.test; ) t.d( ); t.e( ); // obavještavanje o događaju je dozvoljeno samo unutar klase Test } } Računarski praktikum 3

  21. Događaji Primjer (pritisak na tipku): U klasi System.Windows.Forms.Button definiran je događaj public event EventHandler Click; koji se obrađuje uz pomoć delegata (iz prostora System) public delegate void EventHandler (object sender, EventArgs e); Računarski praktikum 3

  22. Događaji Moguće je koristiti i generički delegat: public delegate void EventHandler<TEventArgs> (object sender, TEventArgs e) where TEventArgs : EventArgs; EventArgs je temeljna klasa koja pruža informacije o događaju. Sadrži samo statičko Empty svojstvo. Računarski praktikum 3

  23. Događaji Primjer 1: Kad u instanci klase Student dođe do promjene vrijednosti varijable ime, objekt odašilje obavijest o događaju PromjenaImena. Taj događaj obrađuje metoda Obavijesti koja se prethodno prijavila za taj događaj preko delegata PromjenaImenaHandler. Računarski praktikum 3

  24. Događaji . public delegate void PromjenaImenaHandler(string s); class Student { string ime; string prezime; public event PromjenaImenaHandler PromjenaImena; public Student(string ime) { this.ime = ime; } public string Ime { get { return ime; } set { if (ime != value) { ime = value; PromjenaImena(ime); } } } } Objavljivanje događaja Računarski praktikum 3

  25. Događaji class Program { public static void Obavijesti(string novoIme) { Console.WriteLine("Ime je promijenjeno u "+novoIme); } static void Main(string[] args) { Student s = new Student("Lana"); s.PromjenaImena += new PromjenaImenaHandler(Obavijesti); s.Ime = "Ana"; } } Prijava za događaj Računarski praktikum 3

  26. Delegate Delegate je bazna klasa za sve delegatske tipove. Radi se o apstraktnoj klasi iz koje ne možemo u izvoditi vlastite klase. Preciznije, svi delegati su izvedeni iz klase MultiCastDelegate koja je bazna klasa za višeodredišne delegate, a ta klasa je izvedena iz klase Delegate. U sljedećem primjeru ćemo vidjeti kako djeluju neke metode iz klase Delegate: Računarski praktikum 3

  27. Delegate class Program { public delegate void MojDelegat(); public static void Metoda1() { Console.Write("m1 "); } public static void Metoda2() { Console.Write("m2 "); } Računarski praktikum 3

  28. Delegate staticvoidMain(string[] args) { MojDelegat d1 = Metoda1; MojDelegat d2 = Metoda2; MojDelegat d3 = (MojDelegat)Delegate.Combine(d1, d2, d2, d1, d1, d2, d1); d3( ); Console.Write("---"); MojDelegat d4 = (MojDelegat)Delegate.Remove(d3, d2); d4( ); Console.Write("---"); MojDelegat d5 = (MojDelegat)Delegate.RemoveAll(d3, d1); d5( ); Console.Write("---"); MojDelegat d6 = (MojDelegat)Delegate.Combine(d4, d5); d6(); } } // m1 m2 m2 m1 m1 m2 m1 --- m1 m2 m2 m1 m1m1 --- m2 m2m2 --- m1 m2 m2 m1 m1m1 m2 m2m2 Računarski praktikum 3

  29. Add, remove public delegate void MojDelegat(); public class C { public event MojDelegat e; } • U prethodnom primjeru je kompilator deklaraciju događaja e • konvertirao u: • privatnu varijablu tipa MojDelegat i • javni par pristupnih funkcija (add, remove) Računarski praktikum 3

  30. Add, remove Dakle, prethodni kod je ekvivalentan sljedećem: public delegate void MojDelegat(); public class C { private MojDelegat d; public event MojDelegat e { add { d+= value; } // Nap: potrebno je implementirati remove { d-=value; } // oba pristupnika } } Računarski praktikum 3

  31. Add, remove public delegate void MojDelegat(); class C { private MojDelegat d; public event MojDelegat e { add { Console.WriteLine("Dodajemo metodu"); d += value; } remove { Console.WriteLine("Oduzimamo metodu"); d -= value; } } public void objavi() { //e(); greška d(); } } class Program { publicstaticvoid f() { Console.WriteLine("Obradjujemodogadjaj"); } staticvoidMain(string[] args) { C c = new C(); c.e += f; c.e += f; c.e -= f; c.objavi(); } } Dodajemo metodu Dodajemo metodu Oduzimamo metodu Obradjujemo dogadjaj Računarski praktikum 3

  32. Sučelja Sintaksa sučelja je [ atributi ] [ modifikatori pristupa ] interface ImeSučelja [: sučelja] { tijelo sučelja } Sučelje za razliku od klasa pruža specifikaciju svojih članova, a ne implementaciju. Klasa može implementirati više sučelja. -------Računarski praktikum 3-------

  33. Sučelja Svi članovi sučelja su (implicitno) apstraktni. Greška je eksplicitno navoditi modifikator pristupa. S druge strane, (apstraktne) klase mogu sadržavati i apstraktne i implementirane članove. Strukture mogu implementirati sučelja, ali ne mogu naslijediti klasu. Sučelja mogu sadržavati metode, svojstva, događaje i indeksere (to su ujedno i članovi klase koji mogu biti apstraktni). Pod implementacijom sučelja podrazumijeva se public implementacija svih njegovih članova. -------Računarski praktikum 3-------

  34. Sučelja interface IPokretljivo { void Pokreni(); void Zaustavi(); } class Auto : IPokretljivo { bool uVoznji; public void Pokreni() { uVoznji = true; } public void Zaustavi() { uVoznji = false; } } -------Računarski praktikum 3-------

  35. Sučelja Klase mogu implementirati i više sučelja. interface IUpaljivo { void Upali( ); void Ugasi( ); } class Auto : IPokretljivo, IUpaljivo { public void Pokreni( ) { //implementacija } public void Zaustavi( ) { //implementacija } public void Upali( ) { //implementacija } public void Ugasi( ) { //implementacija } } Moramo dodati i ove implementacije. -------Računarski praktikum 3-------

  36. Sučelja Sučelje se može izvesti iz nekog drugog sučelja i pritom nasljeđuje sve njegove članove. interface IVozilo: IPokretljivo { void Upali(); void Ugasi(); } U prethodnom primjeru sučelje IVozilo dakle proširuje sučelje IPokretljivo. -------Računarski praktikum 3-------

  37. Sučelja class Auto : IVozilo { bool uVoznji; bool upaljeno; public void Pokreni() { uVoznji = true; } public void Zaustavi() { uVoznji = false; } public void Upali() { upaljeno = true; } public void Ugasi() { upaljeno = false; } } -------Računarski praktikum 3-------

  38. Sučelja interface I1 { … } interface I2 : I1 { … } class C : I2 { … } class Program { static void Main(string[] args) { C c = new C(); I1 i1 = c; I2 i2 = c; i1 = i2; // i2 = i1; greška i2=(I2)i1; } } -------Računarski praktikum 3-------

  39. Sučelja Metode kao povratni tip mogu imati i sučelje. To je apstraktniji način definiranja metode. Označava da metoda kao povratni tip prima bilo koju klasu (ili strukturu ) koja implementira zadano sučelje. Dozvoljena je i ovakva definicija varijable: IPokretljivo auto1=new Auto(); // auto1.Upali(); auto1.Pokreni(); ((Auto)auto1).Upali(); -------Računarski praktikum 3-------

  40. Sučelja U sljedećem primjeru sučelje sadrži događaj. public delegate void Delegat(); public interface I { event Delegat e; // Delegat d; U sučelju se ne može nalaziti delegat! void Objavi(); } -------Računarski praktikum 3-------

  41. Sučelja public class C : I { public event Delegat e; /* ovaj redak može predstavljati implementaciju događaja */ public void Objavi() { if (e != null) e(); } } publicclass Program { staticprivatevoid f() { Console.WriteLine("Dogodio se dogadjaj :)."); } staticpublicvoidMain() { I i = new C(); // sad sve možemo izvršiti i preko sučelja i.e += f; i.Objavi(); } } -------Računarski praktikum 3-------

  42. Sučelja Primjer: implementacija svojstva i indeksera iz sučelja. public interface I { int Broj { get; set; } int this[int index] { get; set;} } Napomena: sučelje može zahtijevati da se implementira samo jedan od pristupnika, međutim to ne sprječava klasu u implementaciji drugog pristupnika. -------Računarski praktikum 3-------

  43. Sučelja public class C : I { public int Broj { get { return broj; } set { broj = value; } } public int this[int index] { get { return niz[index]; } set { niz[index] = value; } } private int broj; private int[] niz=new int[10]; } -------Računarski praktikum 3-------

  44. Sučelja U dosadašnjim primjerima klasa je implementirala metodu iz sučelja implicitno. Klasa ili struktura mogu implementirati više sučelja koja sadrže metodu s istim potpisom. U tom slučaju, ako želimo imati različite implementacije, možemo metodu implementirati i eksplicitno. Pritom se ne navodi modifikator pristupa. Da bi se takva metoda pozvala, potrebno je kastati varijablu tipa klase u tip sučelja. -------Računarski praktikum 3-------

  45. Sučelja interface I1 { void f( ); } interface I2 { void f( ); } interface I3 { void f( ); } class C : I1, I2, I3 { public void f() { Console.Write(“Prva f”); } void I2.f(){ Console.Write(“Druga f”); } void I3.f() { Console.Write(“Treca f”); } } class Program { static void Main(string[] args) { C cobj = new C(); cobj.f(); I2 i2 = cobj; i2.f(); } } //eksplicitne implementacije -------Računarski praktikum 3-------

  46. Sučelja Ako želimo metodu koja implementira sučelje označiti kao virtualnu, ta metoda mora implicitno implementirati sučelje. Nadjačavanje takve metode se radi standardno pomoću ključne riječi override. U izvedenoj klasi može se napraviti reimplementacija metode iz bazne klase koja implementira sučelje, bilo da se pritom radi o eksplicitnoj ili implicitnoj implementaciji. -------Računarski praktikum 3-------

  47. Sučelja interface I { void f(); void g(); void h(); } class A : I { public virtual void f() { Console.WriteLine("A"); } void I.g() { Console.WriteLine("A"); } public void h() { Console.WriteLine("A"); } } class B : A { public override void f(){ onsole.WriteLine("B"); } public new void g() { Console.WriteLine("B"); } public new void h() { Console.WriteLine("B"); } } class Program { static void Main(string[] args) { B b= new B(); b.f(); ((A)b).f(); ((I)b).f(); // B B B b.g(); ((I)b).g(); //((A)b).g(); // B A b.h(); ((A)b).h(); ((I)b).h(); // B A A } } -------Računarski praktikum 3-------

More Related