Download as pdf or txt
Download as pdf or txt
You are on page 1of 57

IFORMACIOI SISTEMI I BAZE PODATAKA II

2008/2009

Auditorne vježbe

.ET i C#

Emir Mešković, dipl.ing.el.

Literatura
C#
• H.Mössenböck: C# to the Point. Addison-Wesley, 2004
• Hejlsberg, Wiltamuth, Golde: The C# Programming Language, Addison-Wesley, 2004
• B.Albahari, P.Drayton, B.Merrill: C# Essentials. O'Reilly, 2001
• Microsoft: C# Language Specification. Microsoft Press, 2001
• S.Robinson et al: Professional C#, Wrox Press, 2001

.ET
• Mössenböck, Beer, Birngruber, Wöß:.ET Application Development. Addison-W., 2002
• J.Gough: Compiling for the .ET Common Language Runtime. Prentice Hall, 2002
• J. Richter: Applied Microsoft .ET Framework Programming. Microsoft Press, 2002

Web Sites
• www.microsoft.com/net/
• msdn.microsoft.com/net/
• www.gotdotnet.com
• www.devhood.com
• www.asp.net
• dotnet.jku.at
Referentne informacije i priručnici za .NET SDK

Überblick 1
Osobine C#
Vrlo sličan Javi
70% Java, 10% C++, 5% Visual Basic, 15% novo

Kao u Javi Kao u C++


• Objektna-orijentacija (jednostruko naslijeđivanje) • Preopterećivanje operatora
• Interfejsi • Pointer aritmetika u unsafe kodu
• Izuzetci (Exceptions) • Neki sintaksni detalji
• Niti (Threads)
• Prostori imena (slični Java paketima)
• Jako tipiziranje
• Skupljanje smeća
• Reflection
• Dinamičko učitavanje koda
• ...

ove osobine u C#

Stvarno nove (u odnosu na Javu) "Sintaksni šlag"


• Parametri koji se pozivaju po referenci • Komponentno-bazirano programiranje
• Stack-alocirani objekti (strukture) - Osobine
• Blok matrice - Događaji
• Enumeratori • Delegati
• Uniformni sistem tipova • Indekseri
• goto naredba • foreach petlja
• Atributi • Boxing / unboxing
• Programiranje na sistemskom nivou • ...
• Verzionisanje

Überblick 2
"Hello World" Program

File Hello.cs
using System;
• importuje prostor imena System
class Hello {
• početna tačka se mora zvati Main
static void Main() {
• ispis na konzolu
Console.WriteLine("Hello World");
}
• naziv fajla i klase ne moraju biti
identični.
}

Kompajliranje (iz Console prozora; proizvodi Hello.exe)


csc Hello.cs
Izvršavanje
Hello

Struktura C# programa
Program

File1.cs File2.cs File3.cs

namespace A {...} namespace B {...} namespace C {...}

class X {...} class Y {...} class Z {...}

• Ako nije naveden ni jedan prostor imena (namespace)


=> podrazumijeva se anonymous namespace
• Prostori imena takođe mogu sadržavati i strukture, interfejse, delegate i enumeratore
• Isti namespace se može "ponovo otvoriti" u drugim fajlovima
• Najednostavniji slučaj: jedna klasa, jedan fajl, podrazumijevani namespace

Überblick 3
Program koji se sastoji od 2 fajla
Counter.cs
class Counter { Kompajliranje
int val = 0;
public void Add (int x) { val = val + x; } csc /target:exe Counter.cs Prog.cs
public int Val () { return val; }
}
Izvršavanje
Prog
Prog.cs
using System;

class Prog {

static void Main() {


Counter c = new Counter();
c.Add(3); c.Add(5);
Console.WriteLine("val = " + c.Val());
}
}

C#
Simboli

Überblick 4
Identifikatori
Sintaksa
Identifikator = (slovo | '_' | '@' ) { slovo | cifra | '_'}.
Unicode!
• Case-sensitive
• "@" se može koristiti za upotrebu ključnih riječi kao identifikatora
- if ... ključna riječ
- @if ... identifikator if
• Mogu sadržavati Unicode escape sekvence (npr. \u03c0 za π)

Primjeri
nekoIme
suma_od3
_10posto
@while identifikator while
π identifikator π
\u03c0 identifikator π
b\u0061ck identifikator back
9

Ključne riječi
abstract as base bool break
byte case catch char checked
class const continue decimal default
delegate do double else enum
event explicit extern false finally
fixed float for foreach goto
if implicit in int interface
internal is lock long namespace
new null object operator out
override params private protected public
readonly ref return sbyte sealed
short sizeof stackalloc static string
struct switch this throw true
try typeof uint ulong unchecked
unsafe ushort using virtual void
volatile while
77 ključnih riječi u C# (Java ima 47 ključnih riječi)

10

Überblick 5
Konvencije dodjele imena
Veličina slova
• Riječi počinju velikim slovima (npr. PrikaziDijalog)
• Prvo slovo veliko, osim za privatne ili lokalne varijable, konstante i polja
konstante velika slova SIZE, MAX_VALUE
lokalne varijable mala slova i, top, sum
privatna polja mala slova data, lastElement
javna polja velika slova Width, BufferLength
osobine velika slova Length, Fullame
konstante enum.a velika slova Red, Blue
metode velika slova Add, IndexOf
tipovi velika slova StringBuilder (predef. tipovi malim slovima: int)
prostori imena velika slova System, Collections

Prva riječ
• Imena void metoda bi trebala početi glagolom (npr. GetHashCode)
• Ostala imena bi trebala početi imenicom (npr. size, IndexOf, Collections)
• Konstante enumeracije ili bool članovi mogu početi pridjevom (Red, Empty)
11

Cijeli brojevi (Integer)


Sintaksa

DecKonstanta = cifra {cifra} {IntSufix}.


HexKonstanta = "0x" hexCifra {hexCifra} {IntSufiks}.
IntSufiks = 'u' | 'U' | 'l' | 'L'.

Tip
bez sufiksa: najmanji tip od int, uint, long, ulong
sufiks u, U: najmanji tip od uint, ulong
sufiks l, L: najmanji tip od long, ulong

Primjeri
17 int
9876543210 long
17L long
17u uint
0x3f int
0x10000 long
0x3fL long
12

Überblick 6
Brojevi sa pokrentim zarezom
Sintaksa (pojednostavljeno)
RealKonstanta = [Cifre] ["." [Cifre]] [Exp] [RealSufiks].
mora imati berem 1 cifru i jedno od ".", Exp, drugi RealSufiks
Cifre = cifra {cifra}.
Exp = ("e" | "E") ["+" | "-"] Cifre.
RealSufiks = "f" | "F" | "d" | "D" | "m" | "M".

Tip
bez sufiksa: double
sufiks f, F: float
sufiks d, D: double
sufiks m, M: decimal
Primjeri
3.14 double
1E-2 double
.1 double
10f float
13

Karakter konstante i stringovi


Sintaksa
KarakterKonstanta = ' char '.
StringKonstanta = " {char} ".
char može biti
Bilo koji karakter osim navodnika, kraja linije ili \
Escape sekvence
\' '
\" "
\\ \
\0 0x0000
\a 0x0007 (alert)
\b 0x0008 (backspace)
\f 0x000c (form feed)
\n 0x000a (new line)
\r 0x000d (carriage return)
\t 0x0009 (horizontal tab)
\v 0x000b (vertical tab)
Unicode- ili heksadecimalne escape sekvence
\u0061 a
\x0061 a
14

Überblick 7
Karakter konstante i stringovi (nastavak)
Primjeri za escape sekvence u stringovima
"file \"C:\\sample.txt\"" file "C:\sample.txt"
"file \x0022C:\u005csample.txt\x0022"

Ako se ispred stringa nalazi @


• karakter \ se ne interpretira kao escape karakter
• svaki karakter " mora biti naveden dva puta
• string se može protezati preko više linija

Primjer

@"file file
""C:\sample.txt""" "C:\sample.txt"

15

Komentari
Jedno-linijski komentari
// komentar

Ograđeni komentari
/* komentar */
ne smije biti ugniježden

Dokumentacioni komentari
/// dokumentacioni komentar

16

Überblick 8
C#
Tipovi

17

Uniformni sistem tipova

Tipovi

Vrijednosni Tipovi Referentni Tipovi Pointeri

Primitivni Tipovi Enums Structs Classes Interfaces Arrays Delegates


bool sbyte byte float
char short ushort double
int uint decimal
long ulong
Korisnički- definisani Tipovi

plavi tipovi ne postoje u Javi

Svi tipovi su kompatibilni sa object


- može biti dodijeljen varijablama tipa object
- sve operacije iz tipa object su primjenjive na njih

18

Überblick 9
Vrijednosni i Referentni Tipovi
Vrijednosni Tipovi Referentni Tipovi
varijabla sadrži vrijednost referencu
smještena na stack heap
inicijalizacija 0, false, '\0' null
dodjela kopira vrijednost kopira referencu

primjer int i = 17; string s = "Hello";


int j = i; string s1 = s;

i 17 s
Hello
j 17 s1

19

Primitivni Tipovi
dugi oblik u Javi opseg
sbyte System.SByte byte -128 .. 127
byte System.Byte --- 0 .. 255
short System.Int16 short -32768 .. 32767
ushort System.UInt16 --- 0 .. 65535
int System.Int32 int -231 .. 231-1
uint System.UInt32 --- 0 .. 232 -1
long System.Int64 long -263 .. 263-1
ulong System.UInt64 --- 0 .. 264-1
float System.Single float ±1.5E-45 .. ±3.4E38 (32 Bit)
double System.Double double ±5E-324 .. ±1.7E308 (64 Bit)
decimal System.Decimal --- ±1E-28 .. ±7.9E28 (128 Bit)
bool System.Boolean boolean true, false
char System.Char char Unicode character

20

Überblick 10
Tip decimal

128 bit-ni tip sa fiksnom decimalnom tačkom


s = 0 or 1
(-1) s * c * 10 -e 0 ≤ c < 296
0 ≤ e ≤ 28

Za kalkulacije sa
• velikim brojevima
• visokom decimalnom tačnošću (npr. 0.1 = 1 * 10 -1)

=> npr. u finansijskoj matematici

21

Kompatibilnost između Primitivnih tipova

decimal double float long int short sbyte

samo sa ulong uint ushort byte


cast

char

Slijedeći izrazi su legalni


intVar = shortVar;
intVar = charVar;
floatVar = charVar;
decimalVar = (decimal) doubleVar;

22

Überblick 11
Enumeratori

Lista imenovanih konstanti

Deklaracija (na namespace nivou)


enum Color {Red, Blue, Green} // vrijednosti: 0, 1, 2
enum Access {Personal=1, Group=2, All=4}
enum Access1 : byte {Personal=1, Group=2, All=4}

Upotreba

Color c = Color.Blue; // enumeratorska konstanta mora biti kvalifikovana


Access a = Access.Personal | Access.Group;
// a sada sadrži "set" vrijednosti
if ((Access.Personal & a) != 0) Console.WriteLine("pristup dozvoljen");

23

Operacije sa Enumeratorima

Validne operacije
poređenja if (c == Color.Red) ...
if (c > Color.Red && c <= Color.Green) ...
+, - c = c + 2;
++, -- c++;
& if ((c & Color.Red) == 0) ...
| c = c | Color.Blue;
~ c = ~ Color.Red;

Kompajler ne provjerava da li je rezultat validna enumerator vrijednost.

Napomena
- Enumeratori ne mogu biti dodijeljeni varijabli tipa int (osim nakon type cast).
- Enumerator tipovi naslijeđuju od object (Equals, ToString, ...).
- Klasa System.Enum obezbjeđuje operacije nad enumeratorima
(Getame, Format, GetValues, ...).
24

Überblick 12
izovi (Arrays)
Jedno-dimenzionalni nizovi
int[] a = new int[3];
int[] b = new int[] {3, 4, 5};
int[] c = {3, 4, 5};
SomeClass[] d = new SomeClass[10]; // niz referenci
SomeStruct[] e = new SomeStruct[10]; // niz vrijednosti (direktno u nizu)

Multidimenzionalni nizovi (nazubljeni)


int[][] a = new int[2][]; // niz referenci na druge nizove
a[0] = new int[] {1, 2, 3}; // ne može se inicijalizirati direktno
a[1] = new int[] {4, 5, 6};

Multidimenzionalni nizovi (pravougaoni)


int[,] a = new int[2, 3]; // blok matrica
int[,] b = {{1, 2, 3}, {4, 5, 6}}; // može biti inicijaliziran direktno
int[,,] c = new int[2, 4, 2];

25

Multidimenzionalni nizovi

azubljeni (kao u Javi) a[0][1]


a
int[][] a = new int[2][]; a[0]
a[0] = new int[3]; a[1]
a[1] = new int[4];

int x = a[0][1];

Pravougaoni (kompaktniji i efikasniji)

int[,] a = new int[2, 3]; a a[0, 1]

int x = a[0, 1];

26

Überblick 13
Ostale osobine nizova

Indeksi počinju od 0

Dužina niza
int[] a = new int[3];
Console.WriteLine(a.Length); // 3
int[][] b = new int[3][];
b[0] = new int[4];
Console.WriteLine("{0}, {1}", b.Length, b[0].Length); // 3, 4
int[,] c = new int[3, 4];
Console.WriteLine(c.Length); // 12
Console.WriteLine("{0}, {1}", c.GetLength(0), c.GetLength(1)); // 3, 4

System.Array obezbjeđuje neke korisne operacije nad nizovima


int[] a = {7, 2, 5};
int[] b = new int[2];
Array.Copy(a, b, 2); // kopira a[0..1] u b
Array.Sort(b);
...

27

Klasa System.String
Može se koristiti kao standardni tip string
string s = "Fata";

apomene
• Stringovi su nepromjenljivi (koristite StringBuilder ako želite modifikoti stringove)
• Mogu se spajati sa +: "Haso " + s
• Mogu se indeksirati: s[i]
• Dužina stringa: s.Length
• Stringovi su referentni tipovi => referentna semantika dodjeljivanja
• ali se njihove vrijednosti mogu komparirati pomoću == i != : if (s == "Fata") ...
• Klasa String definiše puno korisnih operacija:
CompareTo, IndexOf, StartsWith, Substring, ...

28

Überblick 14
izovi varijabilne dužine
using System;
using System.Collections;

class Test {
static void Main() {
ArrayList a = new ArrayList();
a.Add("Fata");
a.Add("Haso");
a.Add("Mujo");
a.Sort();
for (int i = 0; i < a.Count; i++)
Console.WriteLine(a[i]);
}
}
Izlaz
Fata
Haso
Mujo
29

Asocijativni nizovi
using System;
using System.Collections;

class Test {

static void Main() {


Hashtable phone = new Hashtable();
phone["Fata"] = 7131;
phone["Mara"] = 7130;
phone["Haso"] = 7132;
foreach (DictionaryEntry x in phone)
Console.WriteLine("{0} = {1}", x.Key, x.Value);
}
}

Izlaz
Fata = 7131
Mara = 7130
Haso = 7132
30

Überblick 15
Strukture
Deklaracija
struct Point {
public int x, y; // polja
public Point (int x, int y) { this.x = x; this.y = y; } // konstruktor
public void MoveTo (int a, int b) { x = a; y = b; } // metode
}

Upotreba
Point p; // još nije inicijalizirana
Point p = new Point(3, 4); // konstruktor inicijalizira objekt na stack-u
p.x = 1; p.y = 2; // pristup polju
p.MoveTo(10, 20); // poziv metode
Point q = p; // vrijednosna dodjela objekta (sva polja su dodijeljena)

apomane
• Strukture su vrijednosni tipovi!
Deklaracija strukture alocira objekt direktno na stack-u ili unutar nekog drugog objekta.
• Strukture ne smiju deklarisati konstruktor bez parametara (imaju jedan podrazumijevano).
Ipak, mogu ga koristiti: p = new Point(); // inicijalizira polja na 0, null, false, ...

31

Klase
Deklaracija
class Rectangle {
Point origin;
public int width, height;
public Rectangle() { origin = new Point(0,0); width = height = 0; }
public Rectangle (Point p, int w, int h) { origin = p; width = w; height = h; }
public void MoveTo (Point p) { origin = p; }
}

Upotreba
Rectangle r = new Rectangle(new Point(10, 20), 5, 5);
int area = r.width * r.height;
r.MoveTo(new Point(3, 3));
Rectangle r1 = r ; // dodjela reference

apomene
• Klase su referentni tipovi;
Njihovi objekti se alociraju na heap-u.
• Operator "new" alocira objekt i poziva njegov konstruktor.
Klase mogu deklarisati konstruktor bez parametara.
32

Überblick 16
Razlike između klasa i struktura

Klase Strukture

Referentni tipovi Vrijednosni tipovi


(objekti se alociraju na heap-u) (objekti se alociraju na stack-u)

podržavaju naslijeđivanje nema naslijeđivanja


(sve klase su izvedene od object) (ali su kompatibilne sa object)

mogu implementirati interfejse mogu implementirati interfejse

mogu deklarisati konstruktor bez ne mogu deklarisati konstruktor bez


parametara parametara

mogu imati destruktor nema destruktora

33

Klasa System.Object
Bazna klasa svih referentnih tipova
class Object {
public virtual bool Equals(object o) {...}
public virtual string ToString() {...}
public virtual int GetHashCode() {...}
...
}

Može se koristiti kao standardni tip object


object obj; // kompajler mapira object u System.Object

Kampitiblnost dodjeljivanja
obj = new Rectangle();
obj = new int[3];

Omogućava metode koje rade na proizvoljnim objektima


void Push(object x) {...}
Push(new Rectangle());
Push(new int[3]);
34

Überblick 17
C#
Izrazi

35

Operatori i njihov prioritet


Primarni (x) x.y f(x) a[x] x++ x-- new typeof sizeof checked unchecked
Unarni + - ~ ! ++x --x (T)x
Multiplikativni * / %
Aditivni + -
Shift << >>
Relacioni < > <= >= is as
Jednakost == !=
Logičko AND &
Logičko XOR ^
Logičko OR |
Uslovno AND &&
Uslovno OR ||
Uslovno c?x:y
Dodjeljivanje = += -= *= /= %= <<= >>= &= ^= |=

Operatori na istom nivou se evaluiraju s lijeva na desno.


Unarni operatori +, -, ~, ! kao i type cast-ovi se evaluiraju s desna na lijevo:
- (int) x ⇔ - ((int) x)
36

Überblick 18
Aritmetički Izrazi
Operandi moraju biti tipa
- numerički ili char
- operandi za ++ i – moraju biti numerički ili enumerator konstante
(++ i – rade takođe i na float i double!)

Tip rezultata
Najmanji numerički tip koji uključuje oba operand tipa, ali najmanje int.

apomene
- uint => long
- ulong => nedozvoljeno

uint • (sbyte | short | int) => long


ulong • (sbyte | short | int | long) => nedozvoljeno
decimal • (float | double) => nedozvoljeno

37

Komparacije
Tipovi operanada
- <, >, <=, >=: numerički, char, enum
- ==, !=: numerički, char, enum, bool, referentni tipovi
- x is T: x: izraz ili proizvoljni tip, T: referentni tip
np.: obj is Rectangle
objOfValueType is IComparable
3 is object
arr is int[]

Tip rezultata
bool

38

Überblick 19
Boolean izrazi (&&, ||, !)
Tip operanada
bool

Tip rezultata
bool

Kratkospojna evaluacija (uslovna evaluacija)


a && b => if (a) b else false
a || b => if (a) true else b

Korisni u
if (p != null && p.val > 0) ...
if (x == 0 || y / x > 2) ...

39

Bit izrazi (&, |, ^, ~)


Tipovi operanada
- & | ^: integer, char, enum, bool
- ~: integer, char, enum
- ako tipovi operanada nisu identični operand s manjim tipom se konvertuje u veći tip prije
operacije

Tip rezultata
- veći od dva operand tipa
- za numeričke tipove i char tip rezultata je barem int

40

Überblick 20
Shift izrazi
Tipovi operanada za x << y i x >> y
- x: integer ili char
- y: int

Tip rtezultata
tip od x, ali barem int

apomena
>> vrši logički shift za unsigned tipove i aritmetički shift za signed tipove

41

Overflow provjere
Overflow se ne provjerava podrazumijevano

int x = 1000000;
x = x * x; // -727379968, nema greške

Overflow provjera se može uključiti

x = checked(x * x); //  System.OverflowException

checked {
...
x = x * x; //  System.OverflowException
...
}

Overflow se može uključiti i pomoću prekidača kompajlera

csc /checked Test.cs

42

Überblick 21
typeof i sizeof

typeof
• Vraća Type deskriptor za zadati tipe
(Type deskriptor nekog object o se može dobiti sa o.GetType()).

Type t = typeof(int);
Console.WriteLine(t.Name); //  Int32

sizeof
• Vraća velilčinu tipa u bajtima.
• Može se primijeniti samo na vrijednosne tipove.
• Može se koristiti u unsafe bloku (veličina struktura može zavisiti od sistema).
Mora se komapjlirati sa csc /unsafe xxx.cs

unsafe {
Console.WriteLine(sizeof(int));
Console.WriteLine(sizeof(MyEnumType));
Console.WriteLine(sizeof(MyStructType));
}

43

C#
Deklaracije

44

Überblick 22
Opseg deklaracije
Područje programa kome pripada deklaracija

Vrste deklarativnih prostora


- namespace: deklaracije klasa, interfejsa, struktura, enumeratora, delegata
- class, interface, struct: deklaracije polja, metoda, ...
- enumerator: deklaracije konstanti enumeratora
- blok: deklaracije lokalnih varijabli

namespace N {
...
class C {
...
void Foo() {
...
if (...) { Blokovi naredbi nisu deklarativni prostori sami za sebe
... već pripadaju deklarativnom prostoru
} zatvarajućeg bloka metode
}
}
}

45

Pravila
Pravila opsega
- Ni jedno ime se ne može deklrisati više od jednom u istom deklrativnom prostoru na istom
nivou.
- Ipak, može biti deklrisano u unutrašnjem deklarativnom prostoru (osim u ugniježdenim
bloku naredbe)

Pravila vidljivosti
- Ime je vidljivo u cijelom njegovom deklarativnom prostoru (lokalne varijable samo od tačke
njihova deklaracije nadalje). Ovo implicira da se neko ime može upotrijebiti prije njegove
deklaracije (osim za lokalne varijable, koje se moraju deklarisati prije upotrebe)
- Ako se jedno ime ponovo deklariše u nekom unutrašnjem deklarativnom prostoru, ono
sakriva isto ime iz vanjskog deklarativnog prostora.
- Generalno, niti jedno ime nije vidljivo izvan njegovog deklarativnog prostora.
- Vidljivost imena deklarisanih u prostorima imena (namespaces), klasama, strukturama i
interfejsima može se kontrolisati pomožu modifikatora public, private, protected i internal.
- Imanima enumeratorskih konstanti se može pristupiti ako su kvalifikovana pomoću imena
njihovog enumerator tipa.

46

Überblick 23
Prostori imena (amespaces)
Fajl: XXX.cs
namespace A {
... klase ...
... interfejsi ...
... strukture ...
... enumeratori ...
... delegati ...
namespace B { // puno ime: A.B
...
}
}

Fajl: YYY.cs
namespace A {
...
namespace B {...}
}

namespace C {...}

Jednaka imena prostora imena u različlitim fajlovima čine jedan deklarativni prostor.
Ugniježdeni prostori imena čine vlastiti deklarativni prostor.
47

Upotreba drugih prostora imena

Color.cs Figures.cs Triangle.cs


namespace Util { namespace Util.Figures { namespace Util.Figures {
public enum Color {...} public class Rect {...} public class Triangle {...}
} public class Circle {...} }
}

using Util.Figures;

class Test {
Rect r; // bez kvalifikatora (zbog using Util.Figures)
Triangle t;
Util.Color c; // sa kvalifikatorom
}

Strani prosotri imena


• moraju ili biti importovani (npr. using Util;)
• ili specificirani u kvalifikovanom imenu (npr. Util.Color)

Većina programa treba prostor imena System => using System;


48

Überblick 24
Klase, Interfejsi, Strukture
class C { // vrijedi i za strukture
... polja, konstante ...
... metode ...
... konstruktori, destruktori ...
... osobine ...
... indekseri ...
... događaji ...
... preopterećeni operatori ...
... ugniježdeni tipovi (klase, interfejsi, strukture, enumeratori, delegati) ...
}
interface IX {
... metode ...
... osobine ...
... indekseri ...
... događaji ...
}

Deklarativni prostor neke podklase ne pripada deklarativnom prostoru njegove bazne


klase
=> mogu se deklarisati ista imena u baznoj klasi i njenim podklasama.

49

Enumeratori
enum E {
... enumeratorske konstante ...
}

50

Überblick 25
Blokovi naredbi
Vrste blokova
void foo (int x) { // blok metode B1
... lokalne varijable ...
if (...) { B2 // ugniježdeni blok
... lokalne varijable ...
}
for (int i = 0; ...) { B3 // ugniježdeni blok
... local variables ...
}
}

Deklarativni prostor bloka uključuje deklarativne prostore svojih ugniježdenih prostora.


B1 B1

B2 B3

• Formalni parametri pripadaju deklarativnom prostoru bloka njihove metode.


• Loop varijabla for naredbe pripada bloku njegove for naredbe.
• Deklaracija lokalne varijable mora prethoditi njenu upotrebu.
51

Deklarisanje lokalnih varijabli


void foo(int a) {
int b;
if (...) {
int b; // greška: b je već deklarisano u vanjskom bloku
int c;
int d;
...
} else {
int a; // greška : a je već deklarisano u vanjskom bloku (parametar)
int d; // ok: nema konflikta sa d u if bloku
}
for (int i = 0; ...) {...}
for (int i = 0; ...) {...} // ok: nema konflikta sa i iz prethodne petlje
int c; // greška : c je već deklarisano u ugniježdenom bloku
}

52

Überblick 26
C#
Naredbe

53

Jednostavne naredbe
Prazna naredba
; // ; je terminator, a ne separator

Dodjeljivanje
x = 3 * y + 1;

Poziv metode
string s = "a,b,c";
string[] parts = s.Split(','); // poziv object metod (ne-statičke)

s = String.Join(" + ", parts); // poziv metode klase (statičke)

54

Überblick 27
if naredba
if ('0' <= ch && ch <= '9')
val = ch - '0';
else if ('A' <= ch && ch <= 'Z')
val = 10 + ch - 'A';
else {
val = 0;
Console.WriteLine("invalid character " + ch);
}

55

switch naredba
switch (country) {
case "England": case "USA":
language = "English";
break;
case "Germany": case "Austria": case "Switzerland":
language = "German";
break;
case null:
Console.WriteLine("no country specified");
break;
default:
Console.WriteLine("don't know the language of " + country);
break;
}

Tip switch izraza


integer, char, enum ili string (null ok kao case labela).
ema padajućeg prolaza (za razliku od C i Java)!
Svaka sekvenca naredbe u case mora biti zavšena sa break (ili return, goto, throw).
Ako ne odgovara niti jedna case labela  default
Ako nije specificiran default  nastavak iza switch naredbe

56

Überblick 28
switch sa Goto
int state = 0;
int ch = Console.Read();
switch (state) {
case 0: if (ch == 'a') { ch = Console.Read(); goto case 1; }
else if (ch == 'c') goto case 2;
else goto default;
case 1: if (ch == 'b') { ch = Console.Read(); goto case 1; }
else if (ch == 'c') goto case 2;
else goto default;
case 2: Console.WriteLine("input valid");
break;
default: Console.WriteLine("illegal character " + ch);
break;
}

57

Petlje
while
while (i < n) {
sum += i;
++;
}

do while
do {
sum += a[i];
i--;
} while (i > 0);

for kratki oblik za


for (int i = 0; i < n; i++) int i = 0;
sum += i; while (i < n) {
sum += i;
i++;
}

58

Überblick 29
foreach naredba
Za iteraciju preko kolekcija i nizova

int[] a = {3, 17, 4, 8, 2, 29};


foreach (int x in a) sum += x;

string s = "Hello";
foreach (char ch in s) Console.WriteLine(ch);

Queue q = new Queue(); // elementi su tipa object


q.Enqueue("John"); q.Enqueue("Alice"); ...
foreach (string s in q) Console.WriteLine(s);

59

Skokovi
break; Za izlazak iz petlje ili switch naredbe.
Nema break sa labelom kao u Javi (upotrijebiti goto umjesto).

continue; Nastavak sa slijedećom iteracijom u petlji.

goto case 3: Može se koristiti u switch naredbi za skok na neku labelu.

myLab:
...
goto myLab; Skok na labelu myLab.
Restrikcije:
- nema skakanja u neki blokk
- nema skakanja izvan finally bloka try naredbe

60

Überblick 30
return naredba
Izlaz iz void metode

void Foo (int x) {


if (x == 0) return;
...
}

Vraćanje neke vrijednosti iz funkcijske metode

int Max (int a, int b) {


if (a > b) return a; else return b;
}

class C {
static int Main() {
...
return errorCode; // Main metoda se može deklarisati kao funkcija;
} // vraćeni error code se može provjeriti
// pomožu system varijable errorlevel
}

61

Izlaz na konzolu
Primjeri
Console.Write(intVal); // preopterećena za sve primitivne tipove
Console.WriteLine(intVal); // za objekte ToString() se poziva automatski

Console.Write("Hello {0}", name); // čuvar pozicije (placeholder)


Console.WriteLine("{0} = {1}", x, y);

Sintaksa placeholder-a
"{" n ["," sirina] [":" format [preciznost]] "}"

n broj argumenta (počev od 0)


sirina širina polja (prekoračena ako je premalena)
pozitivan = desno poravnanje, negativan = lijevo poravnanje
format kod za formatiranje (npr. d, f, e, x, ...)
preciznost broj decimalnih cifri (ponekad broj cifri)

Primjer: {0,10:f2}

62

Überblick 31
Format kodovi za brojeve
d, D decimalni format (cijeli broj sa vodećim nulama) -xxxxx
preciznost = broj cifara

f, F format sa fisknom tačkom -xxxxx.xx


preciznost = broj decimalnih cifara (podrazumijevano = 2)

n, N brojčani format (sa separatorom za hiljade) -xx,xxx.xx


preciznost = broj decimalnih cifara (podrazumijevano = 2

e, E format sa pokretnom tačkom (veličina slova je bitna) -x.xxxE+xxx


preciznost = broj decimalnih cifara

c, C novčani format $xx,xxx.xx


preciznost = broj decimalnih cifara (podrazumijevano = 2)
negativne vrijednosti se zatvaraju u zagrade ($xx,xxx.xx)

x, X hexadecimalni format (veličina slova je bitna) xxx


preciznost = broj hex cifaras (moće biti vodeća 0)

g, G generalni (najkompaktniji format za datu vrijednost; podrazumijevan)

63

Primjeri
int x = 17;

Console.WriteLine("{0}", x); 17
Console.WriteLine("{0,5}", x); 17

Console.WriteLine("{0:d}", x); 17
Console.WriteLine("{0:d5}", x); 00017

Console.WriteLine("{0:f}", x); 17.00


Console.WriteLine("{0:f1}", x); 17.0

Console.WriteLine("{0:E}", x); 1.700000E+001


Console.WriteLine("{0:E1}", x); 1.7E+001

Console.WriteLine("{0:x}", x); 11
Console.WriteLine("{0:x4}", x); 0011

64

Überblick 32
String formatiranje
Pomoću ToString za numeričke tipove (int, long, short, ...):
string s;
int i = 12;
s = i.ToString(); // "12"
s = i.ToString("x4"); // "000c"
s = i.ToString("f"); // "12.00"

Pomoću String.Format za prooizvoljne tipove


s = String.Format("{0} = {1,6:x4}", name, i); // "val = 000c"

Lokalno-specifično formatiranje
s = i.ToString("c"); // "$12.00"
s = i.ToString("c", new CultureInfo("en-GB")); // "£12.00"
s = i.ToString("c", new CultureInfo("de-AT")); // " 12.00"

65

Formatirani izlaz u fajl


using System;
using System.IO;

class Test {

static void Main() {


FileStream s = new FileStream("output.txt", FileMode.Create);
StreamWriter w = new StreamWriter(s);

w.WriteLine("Tabela kvadrata:");
for (int i = 0; i < 10; i++)
w.WriteLine("{0,3}: {1,5}", i, i*i);

w.Close();
}

Nije moguće imati više StreamWriter-a koji rade na istom stream-u u isto vrijeme.

66

Überblick 33
Ulaz sa tastature
int ch = Console.Read();
vraća slijedeći karakter.
ćeka dok korisnik ne pritisne return taster.
npr. unos: "abc" + return taster.
Read vraća: 'a', 'b', 'c', '\r', '\n'.
nakon posljednjeg karaktera (Ctrl-Z + return) Read vraća -1

string linija = Console.ReadLine();


vraća slijedeću liniju (nakon Ctrl-Z+CR+LF vraća null).

čeka dok korisnik ne pritisne return taster.


vraća liniju bez CR, LF.

Ne postoji Tokenizer za formatirani ulaz kao u Javi.

67

Ulaz iz fajla
using System;
using System.IO;

class Test {

static void Main() {


FileStream s = new FileStream("input.txt", FileMode.Open);
StreamReader r = new StreamReader(s);

string line = r.ReadLine();


while (line != null) {
...
line = r.ReadLine();
}

r.Close();
}

Nije moguće imati više StreamReader-a koji rade na istom stream-u u isto vrijeme.

68

Überblick 34
Čitanje parametara komandne linije
using System;

class Test {

static void Main(string[] arg) { // npr. pozvana sa : Test value = 3


for (int i = 0; i < arg.Length; i++)
Console.WriteLine("{0}: {1}", i, arg[i]); // izlaz:
// 0: value
// 1: =
// 2: 3
foreach (string s in arg)
Console.WriteLine(s); // izlaz:
// value
// =
// 3
}
}

69

C#
Klase i Strukture

70

Überblick 35
Sadržaj Klasa i Struktura
class C {
... pojja, konstante ... // za objektno-orijentisano programiranje
... metode ...
... konstruktori, destruktori ...

... osobine ... // za komponentno-bazirano programiranje


... događaji ...

... indekseri ... // radi ugodnosti


... preopterećeni operatori ...

... ugniježdeni tipovi (klase, interfejsi, strukture, enumeratori, delegati) ...


}

71

Klase
class Stack {
int[] values;
int top = 0;
public Stack(int size) { ... }
public void Push (int x) {...}
public int Pop() {...}
}

• Objekti se alociraju na heap-u (klase su referentni tipovi)


• Objekti se moraju kreirati sa new

Stack s = new Stack(100);

• Klase mogu naslijediti od jedne druge klase (jednostgruko naslijeđivanje koda)


• Klase mogu implementirati više interfejsa (višestruko naslijeđivanje tipova)

72

Überblick 36
Strukture
struct Point {
int x, y;
public Point(int x, int y) { this.x = x; this.y = y; }
public MoveTo (int x, int y) {...}
}

• Objekti se alociraju na stack-u a ne na heap-u (strukture su vrijednosni tipovi)


+ efikasnost, manja potrošnja memorije, ne opterećuju skupljač smeća.
- žive dok i njihov kontejner (nisu pogodne za dinamičke strukture podataka)
• Mogu se alocirati sa new
Point p; // polja od p nisu još inicijalizirana
Point q = new Point();
• Polja se ne mogu inicijalizirati pri deklaraciji
struct Point {
int x = 0; // kompilaciona greška
}
• Ne mogu se deklarisati konstruktori bez parametara
• Ne mogu naslijediti niti biti naslijeđeni, ali mogu implementirati interfejse

73

Modifikatori vidljivosti (izvod)


public vidljiv gdje je deklaracioni prostor imena poznat
- Članovi interfejsa i enumeratori su podrazumijevano public.
- Tipovi u nekom prosotru imena (klase, strukture, interfejsi,
enumeratori, delegati) imaju podrazumijevanu vidljivost
internal (vidljivi u deklaracionom assembly-ju)
private vidljiv samo u deklaracionoj klasi ili strukturi
- Članovi klasa i struktura su podrazumijevano private
(polja, metode, osobine, ..., ugniježdeni tipovi)

Primjer
public class Stack {
private int[] val; // i podrazumijevano je private
private int top; // i podrazumijevano je private
public Stack() {...}
public void Push(int x) {...}
public int Pop() {...}
}

74

Überblick 37
Pristup private članovima
class B {
private int x;
...
}

class C {
private int x;

public void f (C c) {
x = ...; // metoda može privatnim članovima ove klase (this).
c.x = ...; // metoda klase C može pristupiti privatnim članovima
// nekog drugog objekta C.
B b = ...;
b.x = ...; // greška! metoda klase C ne može pristupiti privatnim članoivima
// neke druge klase.
}
}

75

Polja i konstante
class C {

int value = 0; Polje


- incijalizacija je opciona
- incijalizacijska vrijednost mora biti izračunljiva pri kompajliranju
- polja strukture ne smiju biti inicijalizirana

const long size = ((long)int.MaxValue + 1) / 4;


Konstanta
- mora biti inicijalizirana
- vrijednost mora biti izračunljiva pri kompajliranju

readonly DateTime date;


Read-only polje
- mora biti inicijalizirano u dekaraciji ili konstruktoru
- vrijednost ne mora biti izračunljiva pri kompajliranju
- vrijednost se ne smije kasnije mijenjati
- zauzima memorijsku lokaciju (kao polje)
}

Pristup unutar klase C Pristup iz drugih klasa


... value ... size ... date ... C c = new C();
... c.value ... c.size ... c.date ...
76

Überblick 38
Statička polja i konstante
Pripadaju klasi a ne objektu
class Rectangle {
static Color defaultColor; // jedno po klasi
static readonly int scale; // -- " --
int x, y, width,height; // jedno po objektu
...
}

Pristup unutar klase Pristup iz drugih klasa


... defaultColor ... scale ... ... Rectangle.defaultColor ... Rectangle.scale ...

Konstante se ne mogu deklarisati kao statičke.

77

Metode
Primjer
class C {
int sum = 0, n = 0;

public void Add (int x) { // procedura


sum = sum + x; n++;
}

public float Mean() { // funkcija (mora vratiti neku vrijednost)


return (float)sum / n;
}
}

Pristup unutar klase C Pristup iz drugih klasa

Add(3); C c = new C();


float x = Mean(); c.Add(3);
float x = c.Mean();

78

Überblick 39
Statičke metode
Operacije nad podacima klase (statičkim poljima)

class Rectangle {
static Color defaultColor;

public static void ResetColor() {


defaultColor = Color.white;
}
}

Pristup unutar klase Rectangle Pristup iz drugih klasa


ResetColor(); Rectangle.ResetColor();

79

Parametri
vrijednosni parametri (ulazni parametri) - "poziv po vrijednosti"
void Inc(int x) {x = x + 1;} - formalni parametar je kopija
void f() {
int val = 3; aktuelnog parametra
Inc(val); // val == 3 - aktuelni parametar je neki izraz
}

ref parametri (tranzijentni parametri) - "poziv po referenci"


void Inc(ref int x) { x = x + 1; } - formalni parametar je alias za
void f() { aktuelni parametar
int val = 3; (dostavlja se adresa aktuelnog parametra)
Inc(ref val); // val == 4 - aktuelni parametar mora biti varijabla
}

out parameters (izlazni parametri) - sličan ref parametrima ali pozivar


void Read (out int first, out int next) { ne dostavlja nikakvu vrijednost.
first = Console.Read(); next = Console.Read(); - ne smije se koristiti unutar metode
} prije nego što dobije vriejdnost.
void f() {
int first, next;
Read(out first, out next);
}

80

Überblick 40
Varijabilni broj parametara
Posljednjih n parametara može biti sekvenca vrijdnosti određenog tipa.

ključna riječ
array tip
params

void Add (out int sum, params int[] val) {


sum = 0;
foreach (int i in val) sum = sum + i;
}

params se ne može koristiti za ref i out parametre

Upotreba
Add(out sum, 3, 5, 2, 9); // sum == 19

Drugi primjer
void Console.WriteLine (string format, params object[] arg) {...}

81

Preopterećivanje Metoda
Više metoda neke klase može imati isto ime
- ako imaju razlilčit broj parametara, ili
- ako imaju razlilčte tipove parametara, ili
- ako imaju razlilčite vrste parametara (vriejdnosni, ref/out)
Primjeri
void F (int x) {...}
void F (char x) {...}
void F (int x, long y) {...}
void F (long x, int y) {...}
void F (ref int x) {...}

Pozivi
int i; long n; short s;
F(i); // F(int x)
F('a'); // F(char x)
F(i, n); // F(int x, long y)
F(n, s); // F(long x, int y);
F(i, s); // nejasno između F(int x, long y) i F(long x, int y); => kompilaciona greška
F(i, i); // nejasno između F(int x, long y) iF(long x, int y); => kompilaciona greška

Preopterećene metode se ne mogu razlikovati samo po svom funkcijskom tipu, po prisustvu


params ili po ref naspram out!

82

Überblick 41
Preopterećivanje Metoda
Preopterećene metode se ne mogu razlikovati samo po svojim funkcijskim tipovima
int F() {...}
string F() {...}
F(); // ako se povratni tip ignoriše, ime F ne može biti razriješeno

Slijdeća preopterećivanja su takođe nedozvoljena

void P(int[] a) {...}


void P(params int[] a) {...}

int[] a = {1, 2, 3};


P(a); // trebalo bi pozvati P(int[] a)
P(1, 2, 3); // trebalo bi pozvati P(params int[] a)

Razlozi za ova ograničenja leže u implementaciji: CIL ne sadrži adresu pozvane metode
već njen opis, koje je identično u oba slučaja.

83

Konstruktori za klase
Primjer
class Rectangle {
int x, y, width, height;
public Rectangle (int x, int y, int w, int h) {this.x = x; this.y = y; width = x; height = h; }
public Rectangle (int w, int h) : this(0, 0, w, h) {}
public Rectangle () : this(0, 0, 0, 0) {}
...
}

Rectangle r1 = new Rectangle();


Rectangle r2 = new Rectangle(2, 5);
Rectangle r3 = new Rectangle(2, 2, 10, 5);

• Konstruktori mogu biti preopterećeni.

• Jedan konstruktor može pozvati drugi konstruktor pomoću this


(specificiran u glavi konstruktora, a ne u njegovom tijelu kao u Javi!).

• Prije poziva nekog konstruktora, polja mogu biti inicijalizovana.

84

Überblick 42
Podrazumijevani konstruktor
Ako niti jedan konstrukotr nije deklarisan u klasi, kompajler generiše
podrazumijevani konstruktor bez parametara :
class C { int x; }
C c = new C();// ok
podrazumijevani konstruktor inicijalizira sva polja kako slijedi:
numerička 0
enumeratori 0
bool false
char '\0'
reference null
Ako je deklarisan jedan konstruktor, ne generišre se podrazumijevani
konstruktor :
class C {
int x;
public C(int y) { x = y; }
}

C c1 = new C(); // kompilaciona greška


C c2 = new C(3); // ok

85

Konstruktori za strukture
Primjer
struct Complex {
double re, im;
public Complex(double re, double im) { this.re = re; this.im = im; }
public Complex(double re) : this(re, 0) {}
...
}
Complex c0; // c0.re i c0.im nisu inicijlazirani
Complex c1 = new Complex(); // c1.re == 0, c1.im == 0
Complex c2 = new Complex(5); // c2.re == 5, c2.im == 0
Complex c3 = new Complex(10, 3); // c3.re == 10, c3.im == 3

• Za svaku strukturu kompajler generiše jedan podrazumijevani konstruktor bez


patrametara (čak i ako postoje drugi konstruktori).
Podrazumijevani konstruktor nuluje sva polja.
• Programeri ne smiju deklarisati konstruktor bez parametara za strukture
(zbog implementacionih razloga CLR-a).
• Konstruktor strukture mora inicijalizirati sva polja.

86

Überblick 43
Statički konstruktori
I za klase i za strukture

class Rectangle {
...
static Rectangle() {
Console.WriteLine("Rectangle initialized");
}
}
struct Point {
...
static Point() {
Console.WriteLine("Point initialized");
}
}

• Mora biti bez parametara (takođe za strukture) i ne smije imati public ili private
modifikatore.
• Smije biti samo jedan statički konstruktor po klasi/strukturi.
• Poziva se jednom prije prve upotrebe datog tipa.
• Koristi se za inicijalizaciju statičkih polja.

87

Destruktori
class Test {

~Test() {
... akcije čišćenja ...
}

• Odgovara finalizatorima u Javi.


• Poziva se za neki objekt prije njegovog uklanjanja od strane skupljača smeća.
• Može se koristiti, na primjer, za zatvaranje otvorenih fajlova.
• Destruktor bazne klase se poziva automatrski na end.
• Nema public ili private.
• Opasan je (oživljavanje objekta) i treba ga izbjegavati
• Strukture ne mgu imati destruktor (razlog nepoznat).

88

Überblick 44
Osobine
Sintaksni "šlag" za get/set metode
class Data { tip osobine
ime osobine
FileStream s;

public string FileName {


set {
s = new FileStream(value, FileMode.Create);
}
get {
"ulazni parametar"
return s.Name; set metode
}
}
}

Koriste se kao "pametna polja"


Data d = new Data();

d.FileName = "myFile.txt"; // poziva set("myFile.txt")


string s = d.FileName; // poziva get()

JIT kompajler često poravnava get/set metode  nema slabljenja efikasnosti.

89

Osobine (nastavak)
Operatori dodjlejivanja rade i na osobinama

class C {
private static int size;

public static int Size {


get { return size; }
set { size = value; }
}
}

C.Size = 3;
C.Size += 2; // Size = Size + 2;

90

Überblick 45
Osobine (nastavak)
get ili set se mogu izostaviti
class Account {
long balance;

public long Balance {


get { return balance; }
}
}

x = account.Balance; // ok
account.Balance = ...; // pogrešno

Zašto su osobine dobra ideja?


• Omogućavaju read-only i write-only polja.
• Magu validirati polje kada mu se pristupi.
• Interfejs i implementacija podatka mogu se razlikovati.
• Zamjena za polja u interfejsima.

91

Preopterećivanje operatora
Statička metoda za implementaciju određenog operatora
struct Fraction {
int x, y;
public Fraction (int x, int y) {this.x = x; this.y = y; }

public static Fraction operator + (Fraction a, Fraction b) {


return new Fraction(a.x * b.y + b.x * a.y, a.y * b.y);
}
}

Upotreba
Fraction a = new Fraction(1, 2);
Fraction b = new Fraction(3, 4);
Fraction c = a + b; // c.x == 10, c.y == 8

• Slijedeći operatori mogu biti preopterećeni:


– aritmetički: +, - (unarni i binarni), *, /, %, ++, --
– relacioni: ==, !=, <, >, <=, >=
– bit operatori: &, |, ^
– drugi: !, ~, >>, <<, true, false
• Mora uvije vratiti rezultat funkcije
• Ako je == (<, <=, true) preopterećen,!= (>=, >, false) mora biti takođe preopterećen.

92

Überblick 46
Operatori konverzije
Implicitna konverzija
- Ako je uvijek moguća bez gubitka preciznosti
- npr. long = int;

Eksplicitna konverzija
- Ako je neohodna run time provjera ili je moguće skračivanje
- npr. int = (int) long;

Konverzioni operatori za korisnički definisane tipove


class Fraction {
int x, y;
...
public static implicit operator Fraction (int x) { return new Fraction(x, 1); }
public static explicit operator int (Fraction f) { return f.x / f.y; }
}

Upotreba
Fraction f = 3; // implicitna konverzija, f.x == 3, f.y == 1
int i = (int) f; // eksplicitna konverzija, i == 3

93

Ugniježdeni tipovi
class A {
private int x;
B b;
public void Foo() { b.Bar(); }
...

public class B {
A a;
public void Bar() { a.x = ...; ... a.Foo(); }
...
} }

class C {
A a = new A();
A.B b = new A.B();
}
Za pomoćne klase koje bi trebale biti sakrivene
- Unutrašnja klasa može pristupiti svim članovima vanjske klase (čak i privatnim).
- Vanjska klasa moće pristupiti samo public članovima unutrašnje klase.
- Ostale klase mogu pristupiti unutrapnjoj klasi samo ako je ona public.
Ugniježdeni tipovi mogu takođe biti strukture, enumeratori, interfejsi i delegati.

94

Überblick 47
Razlike prema Javi
• ema anonymous tipova kao u Javi
• Različita podrazumijevana vidljivost za članove
C#: private
Java: package
• Različita podrazumijevana vidljivost za tipove
C#: internal
Java: package

95

C#
Naslijeđivanje

96

Überblick 48
Sintaksa
class A { // bazna klasa
int a;
public A() {...}
public void F() {...}
}

class B : A { // podklasa (naslijeđuje od A, proširuje A)


int b;
public B() {...}
public void G() {...}
}

• B naslijeđuje a i F(), te dodaje b i G()


- konstruktori se ne naslijeđuju
- naslijeđene metode se mogu redefinisati (kasnije)
• Jednostruko naslijeđivanje: jedna klasa može naslijediti samo jednu bane klase, ali
mož implmentirati više interfejsa.
• Klasa može naslijediti samo klasu, a ne i strukturu.
• Strukture ne mogu naslijeđivati druge tipove, ali mogu implementirati interfejse.
• Klasa bez eksplicitne bazne klase naslijeđuje klasu object.

97

Preopterećivanje metoda
Samo metode koje su deklarisane kao virtual mogu biti redefinisane (overridden) u
podklasama
class A {
public void F() {...} // ne može biti redefinisana
public virtual void G() {...} // može biti redefinisana u nekoj podklasi
}

Redefinirajuća (Overriding) metoda mora biti deklarisana sa override


class B : A {
public void F() {...} // upozorenje: sakriva naslijeđenu F()  koristi new
public void G() {...} // upozorenje: sakriva naslijeđenu G()  koristi new
public override void G() { // ok: redefiniše naslijeđenu G
... base.G(); // poziva naslijeđenu G()
}
}

• Potpisi (signatures) metoda moraju biti identični


- isti broj i tipovi parametara (uključivo tip funkcije)
- ista vidljivost (public, protected, ...).
• Osobine i indekseri takođe mogu biti redefinisani (virtual, override).
• Statičke metode ne mogu biti redefinisane.

98

Überblick 49
Dinamičko povezivanje - Binding (pojednostavljeno)

class A {
public virtual void WhoAreYou() { Console.WriteLine("Ja sam A"); }
}

class B : A {
public override void WhoAreYou() { Console.WriteLine(" Ja sam B"); }
}

Poruka poziva metodu koja pripada dinamičkom tipu primaoca


(nije baš uvijek tako, vidi kasnije)
A a = new B();
a.WhoAreYou(); // "I sam B"

Korist: svaka metoda koja može raditi sa A može raditi i sa B


void Use (A x) {
x.WhoAreYou();
}

Use(new A()); // "I sam A"


Use(new B()); // "I sam B"

99

Sakrivanje
Članovi mogu biti deklarisani sa new u podklasi.
Oni sakrivaju naslijeđene članove sa istim imenom i potpisom.

class A {
public int x;
public void F() {...}
public virtual void G() {...}
}

class B : A {
public new int x;
public new void F() {...}
public new void G() {...}
}

B b = new B();
b.x = ...; // pristupa B.x
b.F(); ... b.G(); // poziva B.F i B.G

((A)b).x = ...; // pristupa A.x!


((A)b).F(); ... ((A)b).G(); // poziva A.F i A.G!

100

Überblick 50
Abstract klase
Primjer
abstract class Stream {
public abstract void Write(char ch);
public void WriteString(string s) { foreach (char ch in s) Write(s); }
}

class File : Stream {


public override void Write(char ch) {... upisivanje ch na disk ...}
}

Napomene
• Abstraktne metode nemaju implementaciju.
• Abstraktne metode su implicitno virtual.
• Ako neka klasa ima abstraktne metode (deklarisane ili naslijeđene) i ona mora biti abstract.
• Ne mogu se kreirati objekti od abstraktne klase.

101

Klasa System.Object
Najviša bazna klasa svih drugih klasa
class Object {
protected object MemberwiseClone() {...}
public Type GetType() {...}
public virtual bool Equals (object o) {...}
public virtual string ToString() {...}
public virtual int GetHashCode() {...}
}

Direktno upotrebljiva:
Type t = x.GetType(); vraća deskriptor tipa (za reflection)
object copy = x.MemberwiseClone(); pravi kopiju (ova metoda je protected!)

Može se redfefinisati u podklasama:


x.Equals(y) treba komparirati vrijednosti od x i y
x.ToString() treba vratiti string oblik od x
int code = x.getHashCode(); treba vratiti hash kod za x

102

Überblick 51
C#
Izuzetci (Exceptions)

103

try naredba
FileStream s = null;
try {
s = new FileStream(curName, FileMode.Open);
...
} catch (FileNotFoundException e) {
Console.WriteLine("file {0} not found", e.FileName);
} catch (IOException) {
Console.WriteLine("some IO exception occurred");
} catch {
Console.WriteLine("some unknown error occurred");
} finally {
if (s != null) s.Close();
}

• catch klauzule se provjeravaju sekvencijalno.


• finally klauzula se uvijek izvršava (ako postoji).
• Naziv Exception parametra se može ispustiti u catch klauzuli.
• Exception tip mora biti izveden od System.Exception.
Ako je parameter ispušten, podrazumijeva se System.Exception.

104

Überblick 52
System.Exception
Osobine
e.Message poruka o grešci kao string;
postavljena sa new Exception(msg);
e.StackTrace trag stack-a poziva metode kao string
e.Source aplikacija ili object koji je izbacio exception
e.TargetSite objekt metode koja je izbacila exception
...

Metode
e.ToString() vraća naziv exception-a i StackTrace
...

105

Izbacivanje (Throwing) Exception


Pogrešnom operacijom (implicitni exception)
Division by 0
Index overflow
Acess via a null reference
...

Throw naredbom (eksplicitni exception)


throw new FunnyException(10);

class FunnyException : ApplicationException {


public int errorCode;
public FunnyException(int x) { errorCode = x; }
}

(Pozivom metode koja izbacuhe exception ali ga ne hvata)


s = new FileStream(...);

106

Überblick 53
Exception hijerarhija (izvod)
Exception
SystemException
ArithmeticException
DivideByZeroException
OverflowException
...
NullReferenceException
IndexOutOfRangeException
InvalidCastException
...
ApplicationException
... ukorisnički-definisani exception-i
...
IOException
FileNotFoundException
DirectoryNotFoundException
...
WebException
...

107

Traženje catch klauzule

F G H
... try { ... ...
F(); G(); H(); throw new FooException(...);
... .... .... ....
} catch (Exc e) {
...
}

Prolazi se unazad kroz lanac poziva dok se ne nađe metoda koja hvata dati tip greške.
Ako se ne pronađe => Program se prekida sa ispiok poziva na stack-u (trace)

Exception-i se ne moraju hvatati u C# (kontrast prema Javi)


Nema razlike između
- checked exceptions koje moraju biti uhvaćene, i
- unchecked exceptions koje ne moraju biti uhvaćene

Prednost: pogodnost
Mana: manje robustan softver

108

Überblick 54
ema throws klauzule u potpisu metode

Java
void myMethod() throws IOException {
... throw new IOException(); ...
}

Pozivač od myMethod mora


- uhvatiti IOException ili
- specificirati IOException u svom vlastitom potpisu

C#
void myMethod() {
... throw new IOException(); ...
}

Pozivačs od myMethod može obraditi IOException ali ne mora.


+ zgodno
- manje robustno

109

C#
Prostori imena

110

Überblick 55
Prostori imana (amespaces)
File: XXX.cs
namespace A {
...
namespace B { // puno ime: A.B
...
}
}
File: YYY.cs
File: ZZZ.cs
namespace A { namespace A.B {
... ...
namespace B {...} }
}

namespace C {...}
• Jedan fajl može deklarisati više prostora imena.
• Jedan prostor imena može biti ponovo otvoren u drugom fajlu.
• Za tipove koji nisu deklarisani niti u jednom prostoruimena, se smatra da su u podrazumijevanom
prostoru imena
(global prostor imena).

111

Upotreba drugih prostora imena

Color.cs Figures.cs Triangle.cs


namespace Util { namespace Util.Figures { namespace Util.Figures {
enum Color {...} class Rect {...} class Triangle {...}
} class Circle {...} }
}

using Util.Figures;

class Test {
Rect r; // bez kvalifikacije (zbog using Util.Figures)
Triangle t;
Util.Color c; // sa kvalifikacijom
}

Strani prostori imena


• moraju biti importovani (npr. using Util;)
• ili specificirani u kvalifikovanom imenu (npr. Util.Color)

112

Überblick 56
C# Prostori imena i Java Paketi

C# Java
Jedan fajl može sadržavati višeprostora imena Jedan fajl može sadržavati samo 1 paket
xxx.cs xxx.java
namespace A {...} package A;
namespace B {...} ...
namespace C {...} ...

Prostori imena i klase nisu mapirani Paketi i klase jesu mapirani u


u direktorije i fajlove direktorije i fajlove
xxx.cs C.java
namespace A { package A;
class C {...} class C {...}
}

Samples Samples

xxx.cs A

C.java

113

Prostori imena i Paketi (nastavak)

C# Java
Importovanje prostora imena Importovanje klasa
using System; import java.util.LinkedList;
import java.awt.*;

Prostori imena se importuju u drugi Namesp. Klase se importuju u fajlove


namespace A { import java.util.LinkedList;
using C; // importuje C u A
} // samo u ovom fajlu
namespace B {
using D;
}

Aliasi su dozvoljeni Java ima vidljivost package


using F = System.Windows.Forms; package A;
... class C {
F.Button b; void f() {...} // package
}
za eksplicitne kvalifikacije i kratka imena
C# ima samo vidljivost internal (!= namespace)
114

Überblick 57

You might also like