RP 3predavanje 02 Programski jezik C q Klase

  • Slides: 36
Download presentation
RP 3/predavanje 02 Programski jezik C#: q Klase (2. dio) 02/10/2020 ----- Računarski praktikum

RP 3/predavanje 02 Programski jezik C#: q Klase (2. dio) 02/10/2020 ----- Računarski praktikum 3 -----Maja Starčević 1

Operatorske funkcije Operatore preopterećujemo pomoću operatorskih funkcija. Ime operatorske funkcije se sastoji od ključne

Operatorske funkcije Operatore preopterećujemo pomoću operatorskih funkcija. Ime operatorske funkcije se sastoji od ključne riječi operator nakon koje slijedi oznaka za operator. Operatorska funkcija mora biti statička i javna. Parametri operatorske funkcije predstavljaju operande. Barem jedan od parametara mora biti istog tipa kao što je tip u kojem je definirana operatorska funkcija. 02/10/2020 -------Računarski praktikum 3 ------- 2

Operatorske funkcije class Kovanica { int vrijednost; public Kovanica(int v) { vrijednost = v;

Operatorske funkcije class Kovanica { int vrijednost; public Kovanica(int v) { vrijednost = v; } public static Kovanica operator + (Kovanica k, int razlika) { return new Kovanica(k. vrijednost + razlika); } } 02/10/2020 -------Računarski praktikum 3 ------- 3

Operatorske funkcije class Program { static void Main(string[] args) { Kovanica maslina = new

Operatorske funkcije class Program { static void Main(string[] args) { Kovanica maslina = new Kovanica(20); Kovanica mrki. Medvjed = maslina + 480; Kovanica slavuj = mrki. Medvjed + (-400); } } 02/10/2020 -------Računarski praktikum 3 ------- 4

Operatorske funkcije Moguće je preopteretiti sljedeće operatore: unarne : + - binarne: + -

Operatorske funkcije Moguće je preopteretiti sljedeće operatore: unarne : + - binarne: + - * == != ! ~ / > ++ % < -- & >= | ^ <= Dakle nije moguće preopteretiti. = && || ? : checked new typeof as is 02/10/2020 -------Računarski praktikum 3 ------- << >> unchecked 5

Operatorske funkcije Moguće je preopteretiti sljedeće operatore: unarne : + - binarne: + -

Operatorske funkcije Moguće je preopteretiti sljedeće operatore: unarne : + - binarne: + - * == != ! ~ / > ++ % < -- & >= | ^ <= Dakle nije moguće preopteretiti. = && || ? : checked new typeof as is 02/10/2020 -------Računarski praktikum 3 ------- << >> unchecked 6

Operatorske funkcije Moguće je još preopterećivati i implicitne i eksplicitne konverzije te literale true

Operatorske funkcije Moguće je još preopterećivati i implicitne i eksplicitne konverzije te literale true i false. Ako preopteretimo operatore poput + i *, onda ćemo implicitno preopteretiti i pripadne složene operatore pridruživanja (+= i *=). Njih je nemoguće eksplicitno preopteretiti. Isto tako, operatori && i || su implicitno preopterećeni ako preopteretimo operatore & i | (npr. && se na tipu T izračunava kao T. false(x) ? x : T. &(x, y) ). 02/10/2020 -------Računarski praktikum 3 ------- 7

Implicitne i eksplicitne konverzije public override string To. String() { return String. Format("Student s

Implicitne i eksplicitne konverzije public override string To. String() { return String. Format("Student s maticnim brojem {0} je {1} {2}", maticni_broj, ime, prezime); } class Student { string ime, prezime; int maticni_broj; public Student (int mb, string i, string p) { maticni_broj=mb; ime=i; prezime=p; } public static explicit operator Student(int i) { return new Student(i, “nepoznati”, “student”); } public static implicit operator int(Student s) { return s. maticni_broj; } } 02/10/2020 -------Računarski praktikum 3 ------- 8

Implicitne i eksplicitne konverzije class Program { static void Main(string[] args) { Student student

Implicitne i eksplicitne konverzije class Program { static void Main(string[] args) { Student student 1 = new Student(1, "Mia", "Mijic"); // student 1 = 1; nije definirana implicitna konverzija iz int u Student student 1 = (Student)1; // eksplicitna konverzija // student 1= Student(1); greška int broj_studenta = student 1; // implicitna konverzija iz Student u int //int broj_studenta = (int)student 1; // može i eksplicitno Console. Write. Line(student 1. To. String()); Console. Write. Line(broj_studenta); } } 02/10/2020 -------Računarski praktikum 3 ------- 9

Implicitne i eksplicitne konverzije U strukuru S (iz jednog od prethodnih primjera dodat ćemo

Implicitne i eksplicitne konverzije U strukuru S (iz jednog od prethodnih primjera dodat ćemo operator implicitne konverzije u int) te ćemo dodati još jednu funkciju f u klasu Program. Kako će se riješiti poziv funkcije? struct S { int x, y; public override string To. String() { return "U strukturi su " + x + " i " + y; } public static implicit operator int(S s) { return s. x + s. y; } } 02/10/2020 -------Računarski praktikum 3 ------- 10

Implicitne i eksplicitne konverzije class Program { static void f(object o) { Console. Write.

Implicitne i eksplicitne konverzije class Program { static void f(object o) { Console. Write. Line("f(object) " + o); } static void f(string s) { Console. Write. Line("f(string) " + s); } static void f(int s) { Console. Write. Line("f(int) " + s); } static void Main(string[] args) { S str = new S(); f(str. To. String()); } } 02/10/2020 -------Računarski praktikum 3 ------- 11

Implicitne i eksplicitne konverzije class Program { static void f(object o) { Console. Write.

Implicitne i eksplicitne konverzije class Program { static void f(object o) { Console. Write. Line("f(object) " + o); } static void f(string s) { Console. Write. Line("f(string) " + s); } static void f(int s) { Console. Write. Line("f(int) " + s); } static void Main(string[] args) { S str = new S(); f(str. To. String()); f(int) 0 f(string) U strukturi su 0 i 0 } } 02/10/2020 -------Računarski praktikum 3 ------- 12

Operatorske funkcije class Cijeli. Broj { public Cijeli. Broj() { i = 0; }

Operatorske funkcije class Cijeli. Broj { public Cijeli. Broj() { i = 0; } public Cijeli. Broj(int a) { i = a; } public static bool operator true(Cijeli. Broj cb) { Console. Write. Line("Operator true"); return !(cb. i == 0); } public static bool operator false(Cijeli. Broj cb) { Console. Write. Line("Operator false"); return cb. i == 0; } public static implicit operator bool(Cijeli. Broj cb) { Console. Write. Line("Implicit operator bool"); return !(cb. i == 0); } private int i; } 02/10/2020 -------Računarski praktikum 3 ------- 13

Operatorske funkcije class Program { static void Main(string[] args) { Cijeli. Broj cb 1

Operatorske funkcije class Program { static void Main(string[] args) { Cijeli. Broj cb 1 = new Cijeli. Broj(); Cijeli. Broj cb 2= new Cijeli. Broj(2); if (cb 1) { } if (cb 1 && cb 2) { } } } Što ispisuje Main? 02/10/2020 -------Računarski praktikum 3 ------- 14

Operatorske funkcije class Program { static void Main(string[] args) { Cijeli. Broj cb 1

Operatorske funkcije class Program { static void Main(string[] args) { Cijeli. Broj cb 1 = new Cijeli. Broj(); Cijeli. Broj cb 2= new Cijeli. Broj(2); if (cb 1) { } if (cb 1 && cb 2) { } } } Što ispisuje Main? Implicit operator bool 02/10/2020 -------Računarski praktikum 3 ------- 15

Operatorske funkcije Što će sad ispisati Main? 02/10/2020 class Cijeli. Broj { public Cijeli.

Operatorske funkcije Što će sad ispisati Main? 02/10/2020 class Cijeli. Broj { public Cijeli. Broj() { i = 0; } public Cijeli. Broj(int a) { i = a; } public static bool operator true(Cijeli. Broj cb) { Console. Write. Line("Operator true"); return !(cb. i == 0); } public static bool operator false(Cijeli. Broj cb) { Console. Write. Line("Operator false"); return cb. i == 0; } /* public static implicit operator bool(Cijeli. Broj cb) { Console. Write. Line("Implicit operator bool"); return !(cb. i == 0); } */ private int i; } -------Računarski praktikum 3 ------- 16

Operatorske funkcije class Program { static void Main(string[] args) { Cijeli. Broj cb 1

Operatorske funkcije class Program { static void Main(string[] args) { Cijeli. Broj cb 1 = new Cijeli. Broj(); Cijeli. Broj cb 2= new Cijeli. Broj(2); if (cb 1) { } // if (cb 1 && cb 2) { } // greška, potrebno je preopteretiti operator & } } Što ispisuje Main? Operator true 02/10/2020 -------Računarski praktikum 3 ------- 17

Uspoređivanje objekata class Broj { public int a; public Broj(int a) { this. a

Uspoređivanje objekata class Broj { public int a; public Broj(int a) { this. a = a; } public override bool Equals(object b) { if (!(b is Broj)) return false; return a == ((Broj)b). a; } } 02/10/2020 -------Računarski praktikum 3 ------- 18

Uspoređivanje objekata Object. Reference. Equals je statička metoda koja provjerava pokazuju li reference na

Uspoređivanje objekata Object. Reference. Equals je statička metoda koja provjerava pokazuju li reference na isti objekt. Object. Equals metoda kod referentnih tipova defaultno isto vrši uspoređivanje na razini referenci, a ne objekata. Object sadrži virtualnu i statičku verziju te metode. Izvedena klasa može nadjačati virtualnu metodu Equals iz klase Object, što utječe i na statičku metodu Equals. Napomena: Kod vrijednosnih tipova nadjačavanje virtualne metode Equals iz klase System. Object je već napravljeno u klasi System. Value. 02/10/2020 -------Računarski praktikum 3 ------- 19

Uspoređivanje objekata Preopterećivanje operatora == kod klasa ima smisla za nepromjenjive tipove, dakle za

Uspoređivanje objekata Preopterećivanje operatora == kod klasa ima smisla za nepromjenjive tipove, dakle za one kod kojih imamo readonly varijable članice. Napomena: ukoliko u nekoj klasi preopteretimo operator==, obavezni smo preopteretiti i pripadni operator !=. 02/10/2020 -------Računarski praktikum 3 ------- 20

Uspoređivanje objekata struct S { int a; public S(int i) { a = i;

Uspoređivanje objekata struct S { int a; public S(int i) { a = i; } Zadatak 1: što ispisuje sljedeći kod? Zadatak 2: što bi ispisao kad bi S bila klasa? 02/10/2020 } class Program { static void Main(string[] args) { S s 1 = new S(1); S s 2 = new S(1); Console. Write. Line(Object. Reference. Equals(s 1, s 1)); Console. Write. Line(Object. Reference. Equals(s 1, s 2)); Console. Write. Line(s 1. Equals(s 1)); Console. Write. Line(s 1. Equals(s 2)); Console. Write. Line(s 1 == s 1); Console. Write. Line(s 1 == s 2); Console. Write. Line((object)s 1 == (object)s 1); Console. Write. Line((object)s 1 == (object)s 2); } } -------Računarski praktikum 3 ------- 21

Uspoređivanje objekata struct S { int a; public S(int i) { a = i;

Uspoređivanje objekata struct S { int a; public S(int i) { a = i; } Rješenje ( S-struktura): 02/10/2020 } class Program { static void Main(string[] args) { S s 1 = new S(1); S s 2 = new S(1); Console. Write. Line(Object. Reference. Equals(s 1, s 1)); Console. Write. Line(Object. Reference. Equals(s 1, s 2)); Console. Write. Line(s 1. Equals(s 1)); Console. Write. Line(s 1. Equals(s 2)); Console. Write. Line(s 1 == s 1); Console. Write. Line(s 1 == s 2); Console. Write. Line((object)s 1 == (object)s 1); Console. Write. Line((object)s 1 == (object)s 2); } } -------Računarski praktikum 3 ------- // // False (pakiranje!) False True == nije definiran False 22

Uspoređivanje objekata class S { int a; public S(int i) { a = i;

Uspoređivanje objekata class S { int a; public S(int i) { a = i; } Rješenje ( S-klasa): 02/10/2020 } class Program { static void Main(string[] args) { S s 1 = new S(1); S s 2 = new S(1); Console. Write. Line(Object. Reference. Equals(s 1, s 1)); Console. Write. Line(Object. Reference. Equals(s 1, s 2)); Console. Write. Line(s 1. Equals(s 1)); Console. Write. Line(s 1. Equals(s 2)); Console. Write. Line(s 1 == s 1); Console. Write. Line(s 1 == s 2); Console. Write. Line((object)s 1 == (object)s 1); Console. Write. Line((object)s 1 == (object)s 2); } } -------Računarski praktikum 3 ------- // // True False 23

Svojstva su članovi klase koji izvan klase izgledaju kao polja, dok unutar klase djeluju

Svojstva su članovi klase koji izvan klase izgledaju kao polja, dok unutar klase djeluju poput funkcije. Svojstva su primjer enkapsulacije. Pomoću svojstava, klasa ima nadzor nad dodjeljivanjem vrijednosti nekoj varijabli, odnosno nad vraćanjem vrijednosti varijable. Pozivatelj pritom ne treba imati uvida u način na koji ta dva procesa djeluju. Student s 1= new Student(); s 1. Ime=“Stipe”; 02/10/2020 -------Računarski praktikum 3 ------- Varijabla ili svojstvo? 24

Svojstva Svojstvo se sastoji od get i set pristupnika: public class Student { string

Svojstva Svojstvo se sastoji od get i set pristupnika: public class Student { string ime; public string Ime { get { return ime; } set { ime=value; } } } 02/10/2020 -------Računarski praktikum 3 ------- 25

Svojstva Svojstvo ne mora nužno biti povezano s jednom određenom varijablom članicom. class Student

Svojstva Svojstvo ne mora nužno biti povezano s jednom određenom varijablom članicom. class Student { string ime, prezime; public Student(string ime, string prezime) { this. ime = ime; this. prezime = prezime; } class Program { static void Main(string[] args) { Student s = new Student("Lara", "Laric"); Console. Write(s. Puno. Ime); } } public string Puno. Ime { get { return ime + " " + prezime; } } } 02/10/2020 -------Računarski praktikum 3 ------- 26

Svojstva U C# 3. 0 postoje automatska svojstva za jednostavno čitanje i pisanje u

Svojstva U C# 3. 0 postoje automatska svojstva za jednostavno čitanje i pisanje u privatne varijable. Kompilator pritom sam vrši implementaciju, identičnu onoj iz prethodnog primjera, te stvara pripadnu privatnu varijablu članicu klase (koju korisnik ne može referirati). public class Student { public string Ime { get; set; } } Napomena: jednom od pristupnika (najčešće set) možemo smanjiti pristup. Dakle, ako želimo imati samo get pristupnik, modifikator pristupa za set postavimo na private (svojstvo se ne smatra automatskim ako nisu navedena oba pristupnika). 02/10/2020 -------Računarski praktikum 3 ------- 27

Svojstva U sljedećem primjeru ćemo jedno svojstvo povezati s korisnički definiranom varijablom članicom, a

Svojstva U sljedećem primjeru ćemo jedno svojstvo povezati s korisnički definiranom varijablom članicom, a drugo će biti automatsko: class Student { private string ime; public string Ime { get { return ime; } set { ime = value; } } public string Prezime { get; set; } } Kako izgleda međukod? 02/10/2020 -------Računarski praktikum 3 ------- 28

Svojstva 02/10/2020 -------Računarski praktikum 3 ------- 29

Svojstva 02/10/2020 -------Računarski praktikum 3 ------- 29

Svojstva class Program { static void Main(string[] args) { Proizvod p = new Proizvod();

Svojstva class Program { static void Main(string[] args) { Proizvod p = new Proizvod(); public class Proizvod { string naziv; int kolicina; Veća kontrola public int Kolicina nad { pridruživanjem get { return kolicina; } varijabli klase. set { if (value<=10) kolicina=value; else throw new Exception("Previse komada. "); } } } 02/10/2020 try { p. Kolicina = 12; } catch (Exception e) { Console. Write(e. Message); } } } -------Računarski praktikum 3 ------- 30

Indekseri služe za pristupanje kolekcijama unutar klase ili strukture. Pristupanje je slično svojstvima, ali

Indekseri služe za pristupanje kolekcijama unutar klase ili strukture. Pristupanje je slično svojstvima, ali se pristupanje vrši pomoću indeksnog argumenta, a ne preko imena svojstva. class Primjer { string[ ] recenica={“Ovo”, “je”, “primjer”}; public string this[int index] { get { return recenica[index]; } set { recenica[index]= value ; } } Pristupanje elementima: Primjer p=new Primjer(); Console. Write. Line (p[2]); // primjer } 02/10/2020 -------Računarski praktikum 3 ------- 31

Indekseri Napomena: indeks pomoću kojeg se pristupa članovima kolekcije ne mora nužno biti tipa

Indekseri Napomena: indeks pomoću kojeg se pristupa članovima kolekcije ne mora nužno biti tipa int. Indekser se ponekad i preopterećuje: public class Klasa { string[] stringovi; public string this[ int indeks ]{ … } public string this[ string indeks ]{ … } } 02/10/2020 -------Računarski praktikum 3 ------- 32

Parcijalne klase Klase (kao ni strukture ni sučelja) ne moraju biti definirane u jednoj

Parcijalne klase Klase (kao ni strukture ni sučelja) ne moraju biti definirane u jednoj datoteci ili bloku. To se postiže pomoću parcijalnih klasa. Takav pristup se često koristi kod većih projekata. public partial class Forma : System. Windows. Form { Automatski generiran kod (Designer) } public partial class Forma { Ručno pisani kod } 02/10/2020 -------Računarski praktikum 3 ------- 33

Parcijalne metode Parcijalni tipovi mogu sadržavati i parcijalne metode. U jednom dijelu parcijalnog tipa

Parcijalne metode Parcijalni tipovi mogu sadržavati i parcijalne metode. U jednom dijelu parcijalnog tipa nalazi se deklaracija metode, dok se u drugom nalazi njezina implementacija. Parcijalne metode moraju imati povratni tip void i implicitno su privatne. 02/10/2020 -------Računarski praktikum 3 ------- 34

Parcijalne metode partial class Kamate { decimal glavnica; partial void Povecaj. Glavnicu (int p);

Parcijalne metode partial class Kamate { decimal glavnica; partial void Povecaj. Glavnicu (int p); } partial class Kamate { partial void Povecaj. Glavnicu(int p) { glavnica=glavnica*(1+p/100); } } 02/10/2020 -------Računarski praktikum 3 ------- 35

Parcijalne metode partial class Test { partial void f(); public void Pozovif(){ } f();

Parcijalne metode partial class Test { partial void f(); public void Pozovif(){ } f(); Console. Write("Pozivam f"); } class Program { static void Main(string[] args) { Test t = new Test(); t. Pozovif(); // f nije implementirana pa se } // poziv neće ni dogoditi } 02/10/2020 -------Računarski praktikum 3 ------- 36