hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih....

30
Programski jezici Beleške sa vežbi - sa kodovima, komentarima i obaveštenjima Drugi kolokvijum <!-- Ispravke, sugestije, mišljenja i ostalo šaljite na [email protected] --> Hijavata

Upload: others

Post on 27-Feb-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Programski jezici

Beleške sa vežbi - sa kodovima, komentarima i obaveštenjima

Drugi kolokvijum

<!-- Ispravke, sugestije, mišljenja i ostalo šaljite na [email protected] -->

Hijavata

Page 2: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

2

Termin 8.

Statičke promenljive i metode

Pogledajmo klasu Racun:

class Racun { public string vlasnik; public double stanje; public double kamata; public Racun(String vlasnik, double stanje, double kamata) { this.vlasnik = vlasnik; this.stanje = stanje; this.kamata = kamata; } static void Main(string[] args) { Racun R1 = new Racun("Pera", 541.45, 0.5); Racun R2 = new Racun("Mika", 457.2, 0.7); } }

Nakon izvršenja ovoga, u memoriji ćemo imati sledeću situaciju:

R1:

R2:

1001

2001

541,45

0,5

P E R A

1002

2002

457,2

0,7

M I K A

Page 3: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

3

Ukoliko nam treba fiksna kamata, koristićemo statičku promenljivu:

class Racun { public string vlasnik; public double stanje; public static double kamata; public Racun(String vlasnik, double stanje) { this.vlasnik = vlasnik; this.stanje = stanje; }

static void Main(string[] args) { Racun.kamata = 0.6; Racun R1 = new Racun("Pera", 541.45); Racun R2 = new Racun("Mika", 457.2); }

}

Nakon izvršenja ovoga, u memoriji ćemo imati sledeću situaciju:

R1:

R2:

Statička promenljiva se ne čuva u instanci klase, već na posebnom delu u memoriji, dge je

definicija klase. Statičkoj promenljivoj se pristupa preko naziva klase, kao što je urađeno u

primeru.

Racun.kamata = 0.6;

Ukoliko bismo pokušali da izmenimo preko instance klase, nećemo uspeti (dobićemo grešku)

upravo zbog toga što ne postoji takvo polje u instanci klase u heap memoriji. Dakle, ne

možemo uraditi sledeće:

R1.kamata = 0.4;

1001 2001

541,45

P E R A

1002 2002

457,2

M I K A

Page 4: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

4

Promena promenljive se preko metode implementira na sledeći način:

public void promeni (double noviIznosKamate) { kamata = noviIznosKamate; // Moguce je i na sledeci nacin Racun.kamata = noviIznosKamate;

}

Postoje i statički konstruktori koji nemaju parametre i služe za inicijalizaciju statičkih

promenljivih. Postoje i statičke klase. U njima je sve statičko.

Statička metoda se poziva, slično statičkoj promenljivoj, preko naziva klase. U njoj ne može

da se pozove neka druga metoda, jer bi ona zahtevala instancu klase. Na primer, ovakva

metoda za smanjenje kamate je moguća:

public static void smanjiKamatu(double smanjenje) { kamata = kamata - smanjenje;

}

S druge strane, ovakva metoda smanjiKamatu() je nemoguća (ne može da pozove neku

nestatičku metodu). Kada bi metoda smanji() bila statička, kod bi bio ispravan (mada

besmislen):

public void smanji(double umanjenje) { kamata = kamata - umanjenje; } public static void smanjiKamatu(double smanjenje) { smanji(smanjenje);

}

Page 5: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

5

Overload operatora

C# pruža mogućnost overloadovanja operatora. Dakle, u okviru klase, moguće je „prekriti“

operator, tj. metodom mu izmeniti osobine. Na primer imamo klasu Razlomak:

class Razlomak { public int brojilac { get; set; } public int imenilac { get; set; } public Razlomak(int br, int im) { brojilac = br; imenilac = im; } public static Razlomak operator + (Razlomak R1, Razlomak R2) { return new Razlomak(R1.brojilac * R2.imenilac + R1.imenilac * R2.brojilac, R1.imenilac * R2.brojilac); }

}

Kada budemo koristili operator + za dva Razlomka, primeniće se postupak koji je prikazan u

metodi, a ne pokušaj običnog sabiranja objekata Razlomak, a koje bi bacilo grešku.

Nizovi/Liste

Pogledati iz onih materijala sa vezbi jednodimenzionalne, dvodimenzionalne, dvostruke

nizove...

ArrayList - niz koji nema predefinisanu duzinu. Metode .add(arg), .Count, .Remove(),

.RemoveAt(index). Prvo se vrši učitavanje kolekcije:

using System.Collections;

Zatim se u kodu, tamo gde je potrebno, deklariše Objekat tipa ArrayList:

ArrayList lista = new ArrayList();

Postoje i spregnute liste:

using System.Collections.Generic;

List<int> brojevi = new List<int>();

Problem sa ArrayListom je taj da su u njemu uvek objekti, pa mora da se konvertuje pri

pozivu.

Page 6: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

6

public static int kvadrat(int a) {

return a * a; } static void Main(string[] args) {

ArrayList a = new ArrayList(); a.Add(3); int t = kvadrat(a[0]);

Console.Write(t);

}

U ovom primeru, zasenčeni deo koda će prijaviti grešku. To je zato što je svaki element

ArrayList-a u stvari instanca klase Object. Main metoda u našem primeru poziva metodu

kvadrat() koja prima parametar u vidu int-a. Međutim, pošto smo mu prosledili objekat,

pobuniće se. Da bismo rešili ovaj problem moramo eksplicitno prevesti Objekat u int:

public static int kvadrat(int a) {

return a * a; } static void Main(string[] args) {

ArrayList a = new ArrayList(); a.Add(3); int t = kvadrat((int)a[0]);

Console.Write(t);

}

Rezultat izvršavanje ove metode biće 9.

* Osnovna razlika između ArrayList i LinkedList je u tome što je ArrayList implementiran kao

niz (koji se pri dodavanju svakog novog elementa ponovo alocira). LinkedList je spregnuta

lista, što znači da se u svakom elemntu čuva i pokazivač na sledeći element. To znači da su

elementi strukture LinkedList „razbacani“ po memoriji:

Nizovi:

int[] niz; - deklarišemo varijablu niz. Zauzima se memorijska lokacija na steku.

niz = new int[];- Ovo ne može. Niz instanciramo navođenjem njegove dužine ili

eksplicitnim navođenjem elemenata:

niz = new int [] { 4, 5, 22 };- Eksplicitno je naveden niz od tri broja.

Page 7: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

7

niz = new int [6];- Rezervisano je 6 mesta na steku za elemente niza. Svakom

elementu je dodeljena vrednost 0 (jer je to default vrednost za int). Da smo imali neki

referentni tip, dodeljena vrednost bi bila null (jer je to default vrednost za referentne

tipove).

Racun [] niz; niz = new Racun [6];

niz[0].stanje = 33.45;- Ovo ne može. Mada će se kompajlirati i buildovati, vratiće grešku,

jer pristupamo nepostojećem elementu Racun (nije instanciran, već je null).

niz[0] = new Racun(33.45);- Ovako može, jer pravimo račun u nizu (pretpostavlja se

postojanje konstruktora koji prima parametar double kao stanje). Sada je već moguće

pristupiti stanju ovog elementa, na primer: niz[0].stanje = 897.3;

Operator is

Služi sa proveru tipa podataka:

public void iteracije () { foreach (Object broj in brojevi) { if (broj is int) Console.Write("Broj"); }

}

Radi isto što i:

Operator as

Ne možemo kastovati (eksplicitno konvertovati) objekte jer može doći do grešaka. Npr, ne

može ovo:

Student s = (Student)osobe[0];

Zato se koristi operator as:

Student s = osobe[0] as Student;

Ako bude moglo, doći će do konverzije. Ako ne, s će dobiti vrednost null (neće biti izuzetaka).

Operator as se koristi samo nad referentnim tipovima.

Čas 9

Page 8: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

8

Stringovi

Sve poznato iz jave...

String.Format

Primeri korišćenja:

string s = string.Format("Ime je {0}, a prezime {1}", "Pera", "Peric");

Ime je Pera, a prezime Peric

Dakle string format funkcioniše tako što imamo string za ispis i u njemu, u vitičastim

zagradama, redni brojevi Stringova koji će se umetati na to mesto. Ostali parametri imaju

redne brojeve (0,1,...) i u zavisnosti od toga se umeću u „glavni“ sting. Evo još primera:

string s = string.Format("Ime je {1}, a prezime {1}", "Pera", "Peric");

Ime je Peric, a prezime Peric

string s = string.Format("Ime je {0}, a prezime {1}. On je {2}.", "Pera", "Peric", "fudbaler");

Ime je Pera, a prezime Peric. On je fudbaler.

Razmotrimo sledeći slučaj.

string s = string.Format("Ime je {0,10}", "Pera");

Ime je Pera.

U ovom slučaju, imamo zapis {0,10}. To znači da se na to mesto umeće String sa „rednim

brojem“ 0, i to tako da se ostavlja ukupno 10 mesta za karaktere, a da se string upisuje „sa

desnim poravnanjem“. Kao da je napisano _ _ _ _ _ _ P e r a . Evo još nekoliko primera:

string s = string.Format("Ime je {0,4}", "Vlastimir");

Ime je Vlastimir

Dakle, iako je ostavljeno 4 mesta, ceo string se ispisao.

string s = string.Format("Ime je {0,-10}.", "Pera");

Ime je Pera .

Ova metoda ima još neke opcije:

Page 9: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

9

string s = String.Format("Cena je {0,-10:C}", 65);

Cena je 65 din

Dakle, String.Format, kada u parametru ima :C, izvlači iz sistema podešavanja za valutu

(currency) i ispisuje je. Postoje ovakva podešavanja i za datum. Imajte na umu da će ispis

zavisiti od sistemskih podešenja za datum:

DateTime dat = new DateTime(2012, 1, 17, 9, 30, 0);

string s = String.Format("Datum je {0}.", dat);

Datum je 17.1.2012 9.30.00.

Ili:

DateTime today = DateTime.Now;

string s = String.Format("Datum je {0}.", today);

Datum je 2.6.2013 1:56:14.

Kratki format datuma (obratite pažnju da se posle godine ne dodaje tačka):

DateTime today = DateTime.Now;

string s = String.Format("Datum je {0:d}", today);

Datum je 2.6.2013

Dugi format datuma (obratite pažnju da se posle godine ne dodaje tačka):

DateTime today = DateTime.Now;

string s = String.Format("Datum je {0:d}", today);

Datum je 2.6.2013

Za procenat:

string s = String.Format("Procenat je {0:p}.", 0.473);

Procenat je 47.30%.

Kao argument se može proslediti i niz.

string[] gradovi = { "Beograd", "New York", "Berlin" };

Page 10: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

10

string s = String.Format("Prvi grad je {0}\n Drugi grad je {1}\n Treci grad je {2}",

gradovi);

Prvi grad je Beograd

Drugi grad je New York

Treci grad je Berlin

Možemo i odrediti koliko decimalnih mesta hoćemo:

double pi = 3.1415926;

string s = String.Format("Pi na dve decimale je {0:N2}, na tri decimale je {0:N3} a

bez decimala {0:N0}.", pi);

Pi na dve decimale je 3.14, na tri decimale je 3.142 a bez decimala je 3.

U prethodnom primeru smo videli kako se prosti tipovi prosleđuju u String.Format (dakle,

nije potrebno koristiti ToString() metodu). Evo još jednog primera:

NE MOŽE MOŽE int a = 3; int b = 6;

Console.Write(a,b);

int a = 3; int b = 6;

Console.Write("{0} {1}",a,b);

Ispis: 3 6

Izuzeci

Hijerarhija izuzetaka:

Exception

SystemException

o ArgumentException

o SystemException

o IOException

o FormatException

o ArytheticException

DivideByZero

o ...

ApplicationException

o OsobaException

try/catch/finaly blok

Svaki od ovih blokova je opcioni

Page 11: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

11

try {

//code that might throw exc } catch (Exception) {

//Handle exception } finally {

//Always done code

}

Try blok - Kod koji može baciti grešku

Catch blok - Kod koji se izvrši ako je greška bačena

Finally blok - uvek se izvršava

Ukoliko je u catch bloku navedeno više Exceptiona, izvršava se prvi koji odgovara.

Sada ćemo istu metodu obraditi na više načina, sa različitim varijacijama i Izuzecima, kako

bismo videli šta se sve dešava:

Page 12: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

12

Ovo je „čist“ primer izvršavanja, bez ijednog izuzetka.

static void Main(string[] args) { Console.WriteLine(1); try { Console.WriteLine(2); Metoda(); Console.WriteLine(3); } catch (DivideByZeroException) { Console.WriteLine(4); } catch (Exception) { Console.WriteLine(5); } finally { Console.WriteLine(6); } Console.WriteLine(7);

}

static void Metoda() {

Console.WriteLine("A"); try {

Console.WriteLine("B"); Console.WriteLine("C");

} catch (DivideByZeroException) {

Console.WriteLine("D"); } catch (ArithmeticException) {

Console.WriteLine("E"); } finally {

Console.WriteLine("F"); }

Console.WriteLine("G"); }

1 2 A B C F G 3 6 7

Ubacujemo DivideByZeroException

static void Main(string[] args) { Console.WriteLine(1); try { Console.WriteLine(2); Metoda(); Console.WriteLine(3); } catch (DivideByZeroException) { Console.WriteLine(4); } catch (Exception) { Console.WriteLine(5); } finally { Console.WriteLine(6); } Console.WriteLine(7);

}

static void Metoda() {

Console.WriteLine("A"); try {

Console.WriteLine("B"); throw new DivideByZeroException(); Console.WriteLine("C");

} catch (DivideByZeroException) {

Console.WriteLine("D"); } catch (ArithmeticException) {

Console.WriteLine("E"); } finally {

Console.WriteLine("F"); }

Console.WriteLine("G"); }

1 2 A B D F G 3 6 7

Page 13: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

13

Pretpostavimo da je bačen izuzetak vezan za neki drugi program (nema veze sa klasom

Exception u C#) static void Main(string[] args) { Console.WriteLine(1); try { Console.WriteLine(2); Metoda(); Console.WriteLine(3); } catch (DivideByZeroException) { Console.WriteLine(4); } catch (Exception) { Console.WriteLine(5); } finally { Console.WriteLine(6); } Console.WriteLine(7);

}

static void Metoda() {

Console.WriteLine("A"); try {

Console.WriteLine("B"); throw new MatlabException(); Console.WriteLine("C");

} catch (DivideByZeroException) {

Console.WriteLine("D"); } catch (ArithmeticException) {

Console.WriteLine("E"); } finally {

Console.WriteLine("F"); }

Console.WriteLine("G"); }

1 2 A B F 6

Bačen je FormatException

static void Main(string[] args) { Console.WriteLine(1); try { Console.WriteLine(2); Metoda(); Console.WriteLine(3); } catch (DivideByZeroException) { Console.WriteLine(4); } catch (Exception) { Console.WriteLine(5); } finally { Console.WriteLine(6); } Console.WriteLine(7);

}

static void Metoda() {

Console.WriteLine("A"); try {

Console.WriteLine("B"); throw new FormatException(); Console.WriteLine("C");

} catch (DivideByZeroException) {

Console.WriteLine("D"); } catch (ArithmeticException) {

Console.WriteLine("E"); } finally {

Console.WriteLine("F"); }

Console.WriteLine("G"); }

1 2 A B F 5 6 7

Page 14: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

14

DivideByZeroException pre try bloka: static void Main(string[] args) { Console.WriteLine(1); try { Console.WriteLine(2); Metoda(); Console.WriteLine(3); } catch (DivideByZeroException) { Console.WriteLine(4); } catch (Exception) { Console.WriteLine(5); } finally { Console.WriteLine(6); } Console.WriteLine(7);

}

static void Metoda() {

Console.WriteLine("A"); throw new DivideByZeroException();

try {

Console.WriteLine("B"); Console.WriteLine("C");

} catch (DivideByZeroException) {

Console.WriteLine("D"); } catch (ArithmeticException) {

Console.WriteLine("E"); } finally {

Console.WriteLine("F"); }

Console.WriteLine("G"); }

1 2 A 4 6 7

DivideByZeroException posle finally bloka:

static void Main(string[] args) { Console.WriteLine(1); try { Console.WriteLine(2); Metoda(); Console.WriteLine(3); } catch (DivideByZeroException) { Console.WriteLine(4); } catch (Exception) { Console.WriteLine(5); } finally { Console.WriteLine(6); } Console.WriteLine(7); }

static void Metoda() {

Console.WriteLine("A"); try {

Console.WriteLine("B"); Console.WriteLine("C");

} catch (DivideByZeroException) {

Console.WriteLine("D"); } catch (ArithmeticException) {

Console.WriteLine("E"); } finally {

Console.WriteLine("F"); }

throw new DivideByZeroException(); Console.WriteLine("G");

} 1 2 A B C F 4 6 7

Page 15: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

15

Ubacujemo DivideByZeroException u try blok i OverflowException u catch(Divide…) blok:

static void Main(string[] args) { Console.WriteLine(1); try { Console.WriteLine(2); Metoda(); Console.WriteLine(3); } catch (DivideByZeroException) { Console.WriteLine(4); } catch (Exception) { Console.WriteLine(5); } finally { Console.WriteLine(6); } Console.WriteLine(7);

}

static void Metoda() {

Console.WriteLine("A"); try {

Console.WriteLine("B"); throw new DivideByZeroException(); Console.WriteLine("C");

} catch (DivideByZeroException) {

Console.WriteLine("D"); throw new OverflowException();

} catch (ArithmeticException) {

Console.WriteLine("E"); } finally {

Console.WriteLine("F"); }

Console.WriteLine("G"); }

1 2 A B D F 5 6 7

Ubacujemo DivideByZeroException u finally blok

static void Main(string[] args) { Console.WriteLine(1); try { Console.WriteLine(2); Metoda(); Console.WriteLine(3); } catch (DivideByZeroException) { Console.WriteLine(4); } catch (Exception) { Console.WriteLine(5); } finally { Console.WriteLine(6); } Console.WriteLine(7);

}

static void Metoda() {

Console.WriteLine("A"); try {

Console.WriteLine("B"); Console.WriteLine("C");

} catch (DivideByZeroException) {

Console.WriteLine("D"); } catch (ArithmeticException) {

Console.WriteLine("E"); } finally {

throw new DivideByZeroException(); Console.WriteLine("F");

} Console.WriteLine("G");

}

1 2 A B C 4 6 7

Page 16: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

16

Ubacuju se dva OverflowExceptiona, u try i finally blokove: (prvi prodje neopazeno)

static void Main(string[] args) { Console.WriteLine(1); try { Console.WriteLine(2); Metoda(); Console.WriteLine(3); } catch (DivideByZeroException) { Console.WriteLine(4); } catch (Exception) { Console.WriteLine(5); } finally { Console.WriteLine(6); } Console.WriteLine(7);

}

static void Metoda() {

Console.WriteLine("A"); try {

Console.WriteLine("B"); throw new FormatException(); Console.WriteLine("C");

} catch (DivideByZeroException) {

Console.WriteLine("D"); } catch (ArithmeticException) {

Console.WriteLine("E"); } finally {

throw new OverflowException(); Console.WriteLine("F");

} Console.WriteLine("G");

}

1 2 A B 5 6 7

Ubacimo DivideByZeroException u try blok, i ubacimo throw (baca tu grešku gde se nalazi) u

catch(DivideByZeroException) blok:

static void Main(string[] args) { Console.WriteLine(1); try { Console.WriteLine(2); Metoda(); Console.WriteLine(3); } catch (DivideByZeroException) { Console.WriteLine(4); } catch (Exception) { Console.WriteLine(5); } finally { Console.WriteLine(6); } Console.WriteLine(7); }

static void Metoda() {

Console.WriteLine("A"); try {

Console.WriteLine("B"); throw new DivideByZeroException(); Console.WriteLine("C");

} catch (DivideByZeroException) {

Console.WriteLine("D"); throw;

} catch (ArithmeticException) {

Console.WriteLine("E"); } finally {

Console.WriteLine("F"); }

Console.WriteLine("G"); }

1 2 A B D F 4 6 7

Page 17: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

17

Ubacimo OverFlowException u try blok i u finaly blok:

static void Main(string[] args) { Console.WriteLine(1); try { Console.WriteLine(2); Metoda(); Console.WriteLine(3); } catch (DivideByZeroException) { Console.WriteLine(4); } catch (Exception) { Console.WriteLine(5); } finally { Console.WriteLine(6); } Console.WriteLine(7);

}

static void Metoda() {

Console.WriteLine("A"); try {

Console.WriteLine("B"); throw new OverflowException(); Console.WriteLine("C");

} catch (DivideByZeroException) {

Console.WriteLine("D"); } catch (ArithmeticException) {

Console.WriteLine("E"); throw new OverflowException();

} finally {

Console.WriteLine("F"); }

Console.WriteLine("G"); }

1 2 A B E F 5 6 7

Doslovni stringovi

U stringovima postoje tzv escape sequence karakteri: \t (tab), \n (linefeed)… Oni umetnuti u string

postavljaju tabulator, prenose u novi red i tako dalje.

String s = "Posle ovoga ide \t tab. \n Ova recenica je u novom redu.";

Posle ovoga ide tab.

Ova rečenica je u novom redu.

Međutim ako hoćemo backslash (\) da koristimo u stringu koristićemo doslovne stringove.Oni se

prave tako što se doda karakter @ ispred stringa: Na primer:

String s = @"Posle ovoga ide \t tab. \n Ova recenica je u novom redu.";

Posle ovoga ide \t.\n Ova rečenica je u novom redu.

Dupliranje navodnika:

String s = @"""pod navodnicima""";

"pod navodnicima"

Page 18: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

18

Termin 10

Generics

Generički tipovi se deklarišu kako bi se neka operacija (ili skup operacija) uopšteno deklarisali

za više tipova podataka. Najbolje kroz primer:

public NekiTip Zameni<NekiTip> (NekiTip a, NekiTip b) { a = b; return a; }

Ovde imamo metodu koja menja vrednosti dva tipa i vraća vrednost prvog parametra. Sada

je moguće pozvati ovu metodu za različite tipove podataka:

static void Main(string[] args) { int a = 56; int b = 32; Console.WriteLine(Zameni<int>(a, b)); }

Ispis će biti: 32

static void Main(string[] args) { string a = "Pera"; string b = "Mika"; Console.WriteLine(Zameni<string>(a, b)); }

Ispis će biti: Mika

Generics se može raditi i sa različitim tipovima podataka (<NekiTip, NekiDrugiTip>).

Međutim ovde postoje znatna ograničenja u pogledu mogućnosti generičkih tipova. Moguće

je formulisati generičku klasu ili strukturu (dakle može i struct isto kao što može i class)

Page 19: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

19

class Podatak <T> { T vrednost; public Podatak(T v) { vrednost = v; } public T Vrednost { get {return vrednost;} } public void Resetuj() { vrednost = default(T); } Podatak<int> P = new Podatak<int>(5); Podatak<string> S = new Podatak<string>("ab"); }

Generički tipovi mogu nasleđivati druge tipove:

class Podatak <T>: NekiTip<T>

Generički tipovi podataka se mogu limitirati. To se čini navođenjem ključne reči where

nakon deklaracije generičke klase (strukture) i njoj nadređenih klasa:

class Podatak <T>: NekiTip<T> where T:class Znači da T može biti bilo koji referentni tip

class Podatak <T>: NekiTip<T> where T:struct

Znači da T može biti bilo koji vrednosni tip

class Podatak <T>: NekiTip<T> where T:Exception

Znači da T može biti tipa Exception ili nekog drugog tipa koji nasleđuje Exception

class Podatak <T>: NekiTip<T> where T:ICloneable

Znači da T može biti bilo koji tip koji implementira interfejs ICloneable

class Podatak <T>: NekiTip<T> where T:new() Znači da T može biti bilo koji tip koji ima default konstruktor

Moguće je i kombinovati ih, npr:

class Podatak <T>: NekiTip<T> where T:struct,Exception

ili

class Podatak <T>: NekiTip<T> where T:ICloneable,IFormattable

Page 20: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

20

Delegati

Delegati su referentni tip podataka

Referenciraju metode

Delegat je nešto kao skup metoda koje se odjednom izvršavaju. Pri tom, te metode se ponašaju kao

stek - dodaju se i skidaju sa vrha. Primer:

public delegate string MojDelegat(int a, bool b); class Osoba { public string C(int x, bool a) { Console.WriteLine("C"); return "C"; } public static string D(int x, bool y) { Console.WriteLine("D"); return "D"; } } class Primer { static void Main(string[] args) { MojDelegat d; d = A; d += Osoba.D; Primer pr = new Primer(); d += pr.B; Osoba o = new Osoba(); d += o.C; d(4, true); } public static string A(int x, bool y) { Console.WriteLine("A"); return "A"; } public string B(int x, bool y) { Console.WriteLine("B"); return "B"; } }

Page 21: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

21

Dakle, prvo je definisan delegat. Vrlo je bitan potpis delegata. Sve metode, koje će delegat referencirati moraju imati isti potpis (istu povratnu vrednost, i iste argumente (isti redosled argumenata)). U našem primeru, delegat ima parametre int i bool koji se ne koriste ni u jednoj od metoda koje delegat poziva, tako da bilo koji poziv delegata (tj. bilo koji argumenti) radi isto.

Delegat možemo posmatrati kao metodu koja je skup metoda koje su naređane nekim redosledom. Pri pozivu delegata (ovde d(4, true);)

Ispis u konzoli će biti:

A D B C

Sada u main dodajemo sledeće(pre d(4, true);): d += A;

Ispis u konzoli će biti:

A D B C A

Međutim, ukoliko sada uradimo sledeće(pre d(4, true);):

d -= A;

Ispis u konzoli će biti:

A D B C

Dakle, izbaciće se poslednja pozvana metoda A (već smo rekli da ovo liči na stek). Sledeći primer (cela Main metoda) će to lepo da ilustruje.:

Page 22: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

22

static void Main(string[] args) { MojDelegat d; d = A; d += Osoba.D; Primer pr = new Primer(); d += pr.B; Osoba o = new Osoba(); d += o.C; d += A; d += pr.B; d += Osoba.D; d += Osoba.D; d(4, true);

}

static void Main(string[] args) { MojDelegat d; d = A; d += Osoba.D; Primer pr = new Primer(); d += pr.B; Osoba o = new Osoba(); d += o.C; d += A; d += pr.B; d += Osoba.D; d += Osoba.D; d -= pr.B; d(4, true);

}

ADBCBDD ADBCDD

“Resetovanje” delegata: Pri dodeli metode (znak =) brišu se sve prethodno dodate metode. Na primer:

MojDelegat d;

d = A;

d += Osoba.D;

d += A;

Primer pr = new Primer();

d = pr.B;

d(4, true);

Ispis: B

Objašnjenje: Prvo je dodata Metoda A, pa D, pa još jednom A. Međutim, kada je delegatu dodeljena metoda B, ona je sve prethodne “izbacila” i ćao zdravo.

Page 23: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

23

Napomene: Ukoliko imamo public delegate string MojDelegat(int a, ref bool b); onda se

delegat ne može pozivati kao gore (npr. d(4, true);). Poziv mora onda ovako da izgleda: bool g = true;

d(4, ref g);

Delegati se mogu međusobno komponovati:

MojDelegat d;

d = A; d += Osoba.D;

Primer pr = new Primer(); d += pr.B;

Osoba o = new Osoba(); d += o.C;

MojDelegat d1;

d1 = A; d1 += Osoba.D;

d += d1;

d(3, true);

Rezultat: ADBCAD

Dakle, delegat d je sadržao metode ADBC, a d1 je sadržao metode AD. Kad su se spojili, metode od d1 su samo dodate na metode delegata d.

Delegati su mutable. To znači da se pri pravljenju delegata, dodavanju ili brisanju metoda, ceo sadržaj promenljive delegat kopira na novu memorijsku lokaciju

Poziv null Delegata je greška. Delegat je null ako nikada nije dodata ni oduzeta nijedna metoda u njemu. Na primer nakon linije MojDelegat d; vrednost delegata d je null.

Poziv praznog Delegata je moguć ( ne izbacije grešku). Delegat je prazan ako su u njemu izbrisane sve prethodno pozivane metode (a pozvana je bar jedna metoda). Na primer: d = A; d -= A;

Page 24: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

24

Događaji

Događaj je polje u klasi čiji je tip delegat.

class Racun { public string vlasnik; public double stanje; public Racun(string ime, double iznos) { this.vlasnik = ime; stanje = iznos; } public bool Isplata(double iznos) { if (stanje > iznos) { stanje -= iznos; } else return false; if (IzvrsenaIsplata != null) IzvrsenaIsplata(); return true; } public static event MojDelegat IzvrsenaIsplata; } public delegate void MojDelegat(); class Banka { List<Racun> Racuni = new List<Racun>(); static void Main(string[] args) { Banka b = new Banka(); b.Racuni.Add(new Racun("Pera", 2000)); Racun rz = new Racun("Zika", 1400); b.Racuni.Add(rz); Racun.IzvrsenaIsplata += b.PovecajBrojIsplata; } int brojIsplata; public void PovecajBrojIsplata() { brojIsplata++; }

}

Page 25: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

25

Kod događaja je bitno nekoliko stvari:

1. Potrebno je prepoznati gde se desio događaj (ovde je to u klasi Racun)

2. Gde se reaguje na događaj (ovde je to u klasi Banka)

3. Gde je event (public static event MojDelegat IzvrsenaIsplata). Treba obratiti

pažnju i na to da li je static ili ne. Pošto je ovde static, u nekom sistemu, odnostio bi se na

svaki račun, u svakoj banci, ne samo u ovoj.

4. Obaveštenje (izvrešenje). Ovde je to: if (IzvrsenaIsplata != null)

IzvrsenaIsplata();

U praksi, ovaj segment koda se izdvaja u neku metodu koja se naziva On* (OnLoad,

OnClick...).

Page 26: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

26

Pripremna nastava

Nivoi pristupa

Imamo sledeći kod:

class Osoba { string ime; public string DajPodatke () { return ime; } } class Student : Osoba { string brIndexa; public string DajPodatke() { return ime + brIndexa; } }

Kompajler će nam prijaviti grešku na osenčenoj liniji koda jer ne može da pristupi polju ime zbog

nivoa pristupa koji ono ima (podrazumevani je private). Zato je neophodno omogućiti u klasi Osoba,

da njen atribut ime bude vidljiv i iz izvedenih klasa. To se radi pomoću ključne reči protected:

class Osoba { protected string ime; public string DajPodatke () { return ime; } } class Student : Osoba { string brIndexa; public string DajPodatke() { return ime + brIndexa; } }

Međutim ovde imamo problem sa metodom DajPodatke(). Iako će se ovaj kod kompajlirati, prijaviće

“potencijalni problem” sa metodom u klasi Student. Proširimo klase odgovarajućim konstruktorima i

napravimo po instancu oba objekta:

Page 27: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

27

class Osoba { protected string ime; public Osoba(string ime) { this.ime = ime; } public string DajPodatke() { return ime; } } class Student : Osoba { string brIndexa; public Student(string ime, string brIndexa) : base(ime) { this.brIndexa = brIndexa; } public string DajPodatke() { return ime + brIndexa; } } class Program { static void Main(string[] args) { Osoba o = new Osoba("Petar"); Student s = new Student("Mika", "133/10"); Console.WriteLine(o.DajPodatke()); Console.WriteLine(s.DajPodatke()); }

}

Ispis: Petar Mika133/10

Dakle, dobili smo očekivan rezultat. Problem će biti ako napravimo sledeću instancu:

Osoba o = new Student("Pera", "234/10"); Console.WriteLine(o.DajPodatke());

Ispis: Pera

Ispis će biti ispis metode u klasi Osoba a ne student (što je i logično, jer imamo instancu klase osoba).

Ovakav problem preklapanja metoda se rešava na dva načina:

Page 28: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

28

1. Da proglasimo metodu DajPodatke u klasi Student novom: public new string DajPodatke()

2. Da metodu DajPodatke() u klasi Osoba proglasimo virtuelnom, i da napišemo da metoda

DajPodatke() u klasi Student daje” novo ponašanje” toj metodi.

3.

Osoba Student public virtual string DajPodatke() public override string DajPodatke()

Ukoliko bismo sada pravili klasu koja nasleđuje studenta i implementira metodu DajPodatke() i ona bi

bila override, i ne bismo morali da eksplicitno navedemo da je ta metoda u Studentu virtuelna jer ona

preko override-a već nasleđuje tu osobinu.

Nakon što smo označili virtual/override metode imamo sledeće slučajeve: Osoba o = new Student("Pera", "234/10"); Osoba d = new Osoba("Mika"); Student s = new Student("Djole", "343/10"); Console.WriteLine(o.DajPodatke()); Console.WriteLine(d.DajPodatke()); Console.WriteLine(s.DajPodatke());

Ispis: Pera234/10

Mika

Djole343/10

Sealed metode i klase

Sealed metode su zaključane, što znači da ne mogu da se override-uju.

public sealed override string DajPodatke();

Ovaj mehanizam služi prvenstveno da se spreči reimplementacija već reimplementirane metode.

Tako na primer, kada bismo zapečatili metodu u klasi Student, onda ona ne bi mogla da se

implementira u nekoj klasi koja bi je nasledila (npr. RedovanStudent). U C# nema smisla pisati sealed

bez override (upravo zbog toga što zaustavlja liniju reimplementacije metode).

Sealed klase su klase kojima zabranjujemo nasleđivanje. Dakle, klasa koja je sealed, ne može se

naslediti.

Apstraktne klase

Apstraktne klase su klase koje služe da obuhvate zajedničke osobine klasa. Apstraktne klase nemaju

instancu. Na primer, kada bismo imali u gornjem primeru:

abstract class Osoba

Onda je nemoguć poziv konstruktora te klase: Osoba d = new Osoba("Mika"); (ovo bi prijavilo

grešku). Međutim ukoliko postoji klasa Student koja nasleđuje klasu Osoba, moguća su sledeća dva

slučaja:

Page 29: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

29

Osoba o = new Student("Pera", "234/10"); Student s = new Student("Djole", "343/10");

Logično je da apstraktne klase ne mogu biti ni sealed ni private.

Apstraktne metode

Apstraktne metode su metode koje nemaju implementaciju (nema vitičastih zagrada)

abstract public string DajPodatke2();

Apstraktne metode mogu postojati samo u apstraktnim klasama. One su zapravo virtualne pa se

pomoću override-a formiraju.

abstract class Osoba { protected string ime; public Osoba(string ime) { this.ime = ime; } abstract public string DajPodatke(); } class Student : Osoba { string brIndexa; public Student(string ime, string brIndexa) : base(ime) { this.brIndexa = brIndexa; } public override string DajPodatke() { return ime + brIndexa; }

}

Page 30: Hijavata - Пушкице | ФОН Андерграунд sa... · 2013-06-18 · promenljivih. Postoje i statičke klase. U njima je sve statičko. Statička metoda se poziva, slično

Hijavata 2013

30

Interfejsi

daju ponašanja

propisuju metode (nikako polja)

svi segmenti su public i ne navodi se modifikator pristupa. Ništa ne može biti static

metode ne mogu biti virtual ili abstract

sve metode interfejsa moraju da se implementiraju (što je i logično jer klasa koja

implementira interfejs, mora biti u stanju da koristi bilo koju od metoda interfejsa, a to je

moguće samo uz implementaciju svake metode)

klasa može implementirati više interfejsa (a naslediti najviše jednu klasu)

Ukoliko apstraktna klasa nasleđuje interfejs, ona ne mora da implementira sve metode interfejsa.

One metode koje ne implementira, treba samo da navede kao Sledeći kod je ispravan:

interface Ipodaci { void Metoda(); int Kvadrat(ref int a); int Metoda3(); } abstract class Podaci : Ipodaci { public void Metoda() { Console.WriteLine("Sve OK."); } public int Kvadrat(ref int podatak) { return podatak*podatak; } public abstract int Metoda3();

}

Međutim, klasa koja nasledi ovakvu apstraktnu klasu, mora da implementira neimplementirane

metode:

class MojiPodaci : Podaci { int jmbg; public override int Metoda3() { return jmbg; }

}

Međutim ako želimo da implementiramo još neku metodu (npr. Metoda() ) moramo je označiti da je

virtual u apstraktnoj metodi, i zatim override u izvedenoj klasi.