24

Click here to load reader

Seminarski Rad OOP

Embed Size (px)

DESCRIPTION

objektno orjentisano programiranje

Citation preview

Page 1: Seminarski Rad OOP

VISOKA TEHNIČKA ŠKOLA STRUKOVNIH STUDIJA BEOGRAD

Bulevar Zorana Đinđića 152a

SEMINARSKI RAD

Predmet: Objektno Orijentisano programiranje

PROFESOR STUDENT

Đorđe Dihovični

Beograd, Jun 2015

Page 2: Seminarski Rad OOP

Contents1. OBJEKTNO ORIJENTISANO PROGRAMIRANJE.....................................................................3

Enkapsuliranje............................................................................................................................................3

Svojstva......................................................................................................................................................5

Destruktori.................................................................................................................................................7

2. METODE..............................................................................................................................................8

Delegati......................................................................................................................................................8

Prikazivanje vrednosti iz metoda.............................................................................................................12

Prosleđivanje argumenata preko reference.............................................................................................13

3. LINQ...................................................................................................................................................13

2

Page 3: Seminarski Rad OOP

1. OBJEKTNO ORIJENTISANO PROGRAMIRANJE

Enkapsuliranje

Enkapsulacija je važan princip kada definišemo klase. Suština je da program koji koristi klasu ne

treba da brine kako ta klasa interno funkcioniše. Program jednostavno kreira instancu klase i

pozia metode te klase. Dokle god metode rade ono za šta su predviđene, program neće brinuti o

načinu na koji su implementirane. Na primer, kada pozovemo metodu Console.WriteLine ne

želimo da nam dosađuju sa svim zamršenim detaljima kako klasa Console fizički određuje kako

će podaci biti ispisani na ekranu. Klasa će možda morati da održava različite vrste internih

informacija o stanju kako bi izvršila svoje razne metode. Ove dodatne informacije o stanju i

aktivnosti, skrivene su od programa oji koristi klasu.

Apstrakcija I enkapsuliranje su srodne funkcije u objektnom orjentisanom programiranju.

Apstrakcja dozvoljava da relevantne informacije budu vidljive I enkapsulacija omogućava

programeru da sprovede željeni nivo apstrakcije.

Enkapsulacija se sprovodi upotrebom prisutnih specifikatora. Pristup specifikatoru definiše obim

I vidljivost člana klase C# podržava sledeće pristupe specifikatora:

Javni (public),

Privatan (private),

Zaštićeni (protected)

Privatni pristup specifikatoru omogućava klasi da sakrije svoje članice funkcija od ostalih

funkcija I objekata. Samo funkcije iste klase može pristupiti privatnom članu.

Javni pristup omogućava klasi da otkrije svaki član podatak I član funkcije drugim funkcijama I

objektima. Svakom javnom članu se može pristupiti unutar klase.

Zaštićeni pristup omogućava “dečju klasu” za pristup članovima podataka I članovima funkcije

same baze. Ovim putem pomaže u sprovođenju nasleđivanja.

Primer za privatan pristup:

using System;namespace RectangleApplication{class Rectangle

3

Page 4: Seminarski Rad OOP

{// članice podatkaprivate double dužina;private double širina;public void Acceptdetail(){Console.WriteLine(“Unesi dužinu :”);dužina=Convert.ToDouble(Console.ReadLine());Console.WriteLine(“Unesi širinu:”);širina=Convert.ToDouble(Console.ReadLine());}public double GetArea{return širina*dužina;}public void Display(){

Console.WriteLine(“Dužina: {0}”, dužina);

Console.WriteLine(“Širina: {0}”, širina);

Console.WriteLine(“Površina: {0}”, GetArea());

}

}

class ExecuteRectangle

{

static void Main(string[] args)

{

Rectangle r=new Rectangle();

r.Accetdetails();

r.Display();

Console.ReadLine();

}}}

4

Page 5: Seminarski Rad OOP

Svojstva

Svojstva (engl. properties) spolja izgledaju kao polja, ali sadrže unutrašnju logiku, kao metode.

Na primer, gledajući sledeći kôd ne možete zaključiti da li je CurrentPrice polje ili svojstvo:

Stock msft = new Stock();

msft.CurrentPrice = 30;

msft.CurrentPrice -= 3;

Console.WriteLine (msft.CurrentPrice);

Svojstvo se deklariše kao polje, ali mu se dodaje blok get/set. Evo kako da implementirate

CurrentPrice kao svojstvo:

public class Stock

{

decimal currentPrice; // Privatno pozadinsko polje

public decimal CurrentPrice // Javno svojstvo

{

get { return currentPrice; }

set { currentPrice = value; }

}

}

get i set su metode za pristupanje svojstvima (engl. property accessors). get se izvršava pri

učitavanju vrednosti svojstva i mora da vrati vrednost istog tipa kao svojstvo. set se izvršava pri

dodeljivanju vrednosti svojstva. set ima implicitan parametar po imenu value, istog tipa kao

svojstvo, koji obično dodeljujete nekom privatnom polju (u ovom slučaju, currentPrice).

Mada se svojstvima pristupa na isti način kao poljima, ona se razlikuju po tome što onome ko ih

implementira daju potpunu kontrolu nad učitavanjem i zadavanjem njihove vrednosti.

Zahvaljujući tome, osoba koja implementira svojstva može da izabere potreban način internog

predstavljanja a da pritom ne otkriva interne detalje korisniku svojstva. U ovom primeru, metoda

set bi generisala izuzetak kada bi value bila izvan važećeg opsega vrednosti. Svojstvo može

samo da se čita ukoliko je zadata samo metoda get, a samo da se upisuje ako je zadata samo

metoda set. Svojstva koja se mogu samo upisivati koriste se retko. Svojstvo obično ima

namensko pozadinsko polje za smeštaj pripadajućih podataka. Međutim, ne

5

Page 6: Seminarski Rad OOP

mora uvek da ga ima – umesto toga, može da vraća vrednost izračunatuna osnovu drugih

podataka.

Primer zadatka korišćenjem get I set pristupa:

using System;

 

namespace Get_Set

{

  class access

   {

     // String Variable declared as private

     private static string name;

     public void print()

      {

        Console.WriteLine("\nMy name is " + name);

      }

 

     public string Name //Creating Name property

      {

        get //get method for returning value

         {

           return name;

         }

        set // set method for storing value in name field.

         {

           name = value;

         }

      }

   }

 

  class Program

   {

6

Page 7: Seminarski Rad OOP

     static void Main(string[] args)

      {

        access ac = new access();

        Console.Write("Enter your name:\t");

        // Accepting value via Name property

        ac.Name = Console.ReadLine();

        ac.print();

        Console.ReadLine();

      }

   }

Destruktori

Destruktor predstavlja specijalnu funkciju članova klase koja se izvršava svaki put kada objekat date klase izađe izvan opsega, pri čemu ima isto ime kao klasa ali poseduje dodat i specijalni znak tilda (~).

Destruktori nikada ne daju vrednost niti mogu sadržati parametre, ne mogu biti nasleđeni niti preopterećeni. Oni su veoma korisni prilikom izlaska iz programa, jer se tada oslobađaju zauzeti resursi iz memorije, zatvaraju otvorene datoteke i tako dalje.

7

Page 8: Seminarski Rad OOP

2. METODE

Delegati

Delegati su tipovi koji umesto promenjivih zadržavaju reference prema metodama, i mogu da

kopiraju ponašanje bilo kog metoda. Za deklarisanje metoda koristi se ključna reč delegate.

8

Page 9: Seminarski Rad OOP

Deklarisanje delegat je slično deklarisanju metoda, osim što oni ne sadrže telo. Delegati sadrže

povratni tip (return type) i skup parametara kao i metodi.

Deklarisanje delegata:

Delegate returnType DelegateName(dt param1, dt param2, ....dt paramN);

Delegat koji je na početku deklarisan prihvata reference za metode koji imaju void povratni tip i

ima dva int parametra.

Prvo se definiše metod koji ne vraća podatke, ali prihvata dva int argumenta. Unutar Main

metode, deklariše se tip delegata koji definišemo. Program pita za dve vrednosti koje treba da

unese korisnik. Za dodeljivanje metoda delegatu koristi se sledeća sintaksa:

variable + new DelegateName(MethodName);

Delegat povezuje pozivajuću metodu s pozvanom metodom u vreme izvršavanja.

Postoje dva aspekta delegata: tip i instanca. Tip delegata definiše protokol kome se pokoravaju

pozivalac i pozvani, koji obuhvata listu parametara tipa i povratni tip. Instanca delegata je bjekat

koji referencira jednu (ili više) pozvanih metoda usklađenih s tim protokolom.

Instanca delegata bukvalno služi pozivaocu kao delegat: pozivalac poziva delegata, a zatim taj

delegat poziva odredišnu metodu. To preusmeravanje razdvaja pozivaoca od odredišne metode.

Deklaraciji tipa delegata prethodi rezervisana reč delegate, ali je inače ona slična deklaraciji

(apstraktne) metode.

Na primer:

delegate int Transformer (int x);

Da bismo napravili instancu delegata, dodelimo metodu promenljivoj delegata:

class Test

{

static void Main()

{

Transformer t = Square; // Pravi instancu delegata

9

Page 10: Seminarski Rad OOP

int result = t(3); // Pokreće delegata

Console.Write (result); // 9

}

static int Square (int x) { return x * x; }

}

Pokretanje delegata je kao pokretanje metode (pošto je namena delegate samo da obezbedi

peusmeravanje):

t(3);

Naredba Transformer t = Square skraćeni je način pisanja naredbe:

Transformer t = new Transformer (Square);

A t(3) je skraćeno od: t.Invoke (3);

Delegat je sličan povratnoj funkciji (engl. callback), opštem terminu koji obuhvata konstrukte

kao što su pokazivači na C funkcije.

Pisanje modularnih metoda pomoću delegata

Promenljivoj delegata metoda se dodeljuje u vreme izvršavanja. To je korisno za pisanje

modularnih metoda (engl. plug-in methods). U ovom primeru, imamo uslužnu metodu Transform

koja primenjuje neku transformaciju na svaki element u celobrojnom nizu. Metoda Transform

ima parametar delegata, pomoću kojeg se zadaje modularna transformacija.

public delegate int Transformer (int x);

class Test

{

static void Main()

{

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

Transform (values, Square);

foreach (int i in values)

Console.Write (i + “ “); // 1 4 9

}

static void Transform (int[] values, Transformer t)

10

Page 11: Seminarski Rad OOP

{

for (int i = 0; i < values.Length; i++)

values[i] = t (values[i]);

}

static int Square (int x) { return x * x; }

}

Višeznačni delegati

Sve instance delegata karakteriše višeznačnost (engl. multicast). To znači da jedna instanca

delegata može da referencira ne samo jednu odredišnu metodu već i listu takvih metoda.

Operatori + i += kombinuju instance delegata.

Na primer:

SomeDelegate d = SomeMethod1;

d += SomeMethod2;

Poslednji red je funkcionalno isti kao:

d = d + SomeMethod2;

Kada se pozove d, time se sada pozivaju i metoda SomeMethod1 i metoda SomeMethod2.

Delegati se pozivaju redosledom kojim su dodati.

Operatori - i -= uklanjaju desni operand delegata iz levog. Na primer:

d -= SomeMethod1;

Pokretanjem d sada će se pokrenuti samo SomeMethod2.

11

Page 12: Seminarski Rad OOP

Primena operatora + ili += na promenljivu delegata čija je vrednost null dozvoljena je, pošto

poziva -= za promenljivu delegata s jednim odredištem (što će rezultovati time da instanca

delegata bude null).

Delegati su nepromenljivi, pa kada pozovemo += ili -=, mi u stvari pravimo novu instancu

delegata i dodeljujemo je postojećoj promenljivoj.

Ako povratni tip višeznačnog delegata (engl. multicast delegate) nije void, pozivalac prima

povratnu vrednost od poslednje metode koja se poziva. Prethodne metode se i dalje pozivaju, ali

se njihove povratne vrednosti odbacuju. U većini scenarija korišćenja višeznačnih delegata,

njihovi povratni tipovi će biti void, pa je ovaj detalj nebitan.

Svi tipovi delegata implicitno se izvode iz System.MulticastDelegate, koji nasleđuje klasu

System.Delegate. C# prevodi operacije +, -, += i -= nad delegatom u statičke metode Combine i

Remove klase System.

Prikazivanje vrednosti iz metoda

Metodi mogu da prikažu vrednost iz bilo kog tipa podataka, i te vrednosti se mogu iskoristiti za

izračunavanje ili dobijanje podataka koje je dati metod izračunao. Važno je znati vrednost koju

metod vraća i kako pristupiti procesiranju dobijenih vrednosti.

Sintaksa za vraćanje vrednosti iz metoda:

returnType MethodName()

{

return value;

}

Tip podatka vrednosti koju metod prikzuje je predstavljena sa returnType. Unutar samog metoda

koristi se ključna reč return na koju se nastavlja vrednost ili izraz koji će dati vrednost. Ukoliko

se ne dobije vrednost, kao povratni tip se može koristiti void.

12

Page 13: Seminarski Rad OOP

Prosleđivanje argumenata preko reference

Argumenti se mogu proslediti preko reference, tako što se zna afresa argument a ne njigova

vrednost. Prosleđivanje preko reference je veoma korisno kada se prosleđuju argument velikih

dimentija, kao što su objekti. Kada se menja ili koristi prosleđeni argument unutar metoda, tada

se menja I izvorna promenljiva na koju se referišemo izvan metoda. Osnovna sintaksa za

definisanje parametara koji prihvataju afresu umesto vrednosti je data sa:

returnType MethodName(ref datatype param1)

{

kod za izvršavanje;

}

Kada se poziva metod i prosleđuje argument, takođe se koristi i ključna reč ref.

MethodName(ref argument);

3. LINQ

LINQ, odnosno Language Integrated Query, omogućava da pišete strukturirane upite sa sigurnim

tipovima za lokalne kolekcije objekata i udaljene izvore podataka.

LINQ omogućava da izvršite upit nad svakom kolekcijom koja implementira interfejs

IEnumerable, bez obzira na to da li je reč o nizu, listi, XML DOM-u, ili udaljenom izvoru

podataka (kao što je tabela na SQL Serveru). Prednosti LINQ-a su i provera tipova u vreme

prevođenja i dinamičko sastavljanje upita.

Dobar način za eksperimentisanje sa LINQ-om jeste preuzimanje LINQPada sa lokacije

http://www.linqpad.net. LINQPad omogućava da interaktivno izvršavamo LINQ upite nad

lokalnim kolekcijama i SQL bazama podataka, a da ne moramo ništa da podešavamo.

13

Page 14: Seminarski Rad OOP

U LINQ-u, osnovne jedinice podataka su sekvence i elementi. Sekvenca je svaki objekat koji

implementira generički interfejs IEnumerable, a element je svaka stavka u toj sekvenci.

U sledećem primeru, names je sekvenca, a Tom, Dick i Harry su elementi:

string[] names = { “Tom”, “Dick”, “Harry” };

Ovakvu sekvencu zovemo lokalna sekvenca zato što predstavlja lokalnu kolekciju objekata u

memoriji.

Upit je izraz koji transformiše sekvence pomoću jednog ili više operatora za upite.

Operator upita (query operator) jeste metoda koja transformiše sekvencu. Tipičan operator upita

prihvata ulaznu sekvencu i proizvodi transformisanu izlaznu sekvencu. U klasi Enumerable, u

imenskom prostoru System.Linq ima oko 40 operatora upita; svi su implementirani kao statičke

proširene metode. Oni se zovu standardni operatori za upite.

LINQ podržava i sekvence koje se mogu dinamički proslediti iz udaljenog izvora podataka kao

što je SQL Server. Te sekvence dodatno implementiraju interfejs IQueryablei podržava ih

odgovarajući skup standardnih operatora za upite u klasi Queryable.

Da bi koristili LINQ u programu, potrebno je uključiti u projekat imenski proctor SystemLinq.

Zatim se deklariše niz od 6 celobrojnih elemenata koji sadrže neke vednosti. Koristi se izraz na

upit na osnovu koga se dobija svaki broj iz niza kome se može priostupiti korišćenjem

rezultujuće promenjive.

Struktura za osnovni izraz za upit:

var query = from range Var in dataSource

<other operations>

Select<projection>;

14

Page 15: Seminarski Rad OOP

Svaka linija formatiranog izraza za upit se naziva klauzula. Postoji sedam tipova klauzula koje se

koriste za izraze za upite: from, select, where, arderby, let, join i group-by.

Izraz za upit počinje klauzulom from. Ova klauzula koristi opseg promenjive koja privremeno

zadržava vrednost iz izvora podataka, nakon koje sledi ključna reč in, a zatim izvor podataka.

Postoji sličnost sa foreach petljom gde promenljiva opsega zadržava vrednost dobijenu iz

izvora podataka.Promenljiva opsega u klauzuli from ima ulogu reference za svaki uzastopni

element iz izvora podataka, automatski prepoznaje tip elemenata, na bazi medjusobnog dejstva

svakog elementa iz izvora podataka.

Na kraju izraza za upit je klauzula select. Posle ključne reči select sledi projekcija koja odradjuje

tip svakog vraćenog elementa. Ukoliko je vrednost u promenljivoj celobrojnog tipa int, tada će

tip upita biti kolekcija celobrojnih tipova.

Rezultat upita je IEnumerable<T>. Moguće je eksplicitno predstaviti tip podatka :

IEnumerable<int>result = from n in numbers

select n;

Pri tome je neophodno znati tip rezultata. Preporuka je zato umesto toga korišćenje tipa

promenljive var.

Najjednostavniji upit se sastoji od jedne ulazne sekvence i jednog operatora. Na primer, evo kako

možemo primeniti operator Where na jednostavan niz da bismo izdvojili imena dugačka

najmanje četiri znaka:

string[] names = { “Tom”, “Dick”, “Harry” };

IEnumerable<string> filteredNames =

System.Linq.Enumerable.Where (names, n => n.Length >= 4);

foreach (string n in filteredNames)

Console.Write (n + “|”); // Dick|Harry|

15

Page 16: Seminarski Rad OOP

Pošto su standardni operatori za upite implementirani kao proširene metode, operator Where

možemo pozvati direktno za names:

IEnumerable<string> filteredNames =

names.Where (n => n.Length >= 4);

(Da bi se ovaj kôd preveo, morate učitati imenski prostor System.Linq pomoću direktive using.)

Metoda Where u imenskom prostoru System.Linq.Enumerable ima sledeći potpis:

static IEnumerable<TSource> Where<TSource> (

this IEnumerable<TSource> source,

Func<TSource,bool> predicate)

source je ulazna sekvenca; predicate je delegat koji se izvršava za svaki ulazni element. Metoda

Where obuhvata sve elemente u izlaznoj sekvenci za koje taj delegat vraća true. Interno, on je

implementiran pomoću iteratora – evo njegovog izvornog koda:

foreach (TSource element in source)

if (predicate (element))

yield return element;

Još jedan od osnovnih operatora za upite jeste metoda Select. Ona transformiše (projektuje) svaki

element iz ulazne sekvence pomoću zadatog lambda izraza:

string[] names = { “Tom”, “Dick”, “Harry” };

IEnumerable<string> upperNames = names.Select (n => n.ToUpper());

foreach (string n in upperNames)

Console.Write (n + “|”); // TOM|DICK|HARRY|

Upit može da projektuje elemente u anonimni tip:

var query = names.Select (n => new {Name = n, Length =n.Length });

foreach (var row in query)

Console.WriteLine (row);

Evo rezultata:

{ Name = Tom, Length = 3 }

{ Name = Dick, Length = 4 }

{ Name = Harry, Length = 5 }

16

Page 17: Seminarski Rad OOP

Za grupisanje, koristi se group by klauzula. Primer za ovu klauzulu:

public class Radnik

{

public string ImeRadnika{get; set;}

public string Radionica{get; set;}

}

public class Program

{

public static void Main()

{

List<Radnik>Radnik )= new List <Radnik>

{

New Radnik{ImeRadnika = “Petar”, Radionica = “MO”},

New Radnik{ImeRadnika = “Zoran”, Radionica = “MB”},

New Radnik{ImeRadnika = “Dragan”, Radionica = “ML”},

New Radnik{ImeRadnika = “Milos”, Radionica = “MO”},

New Radnik{ImeRadnika = “Milan”, Radionica = “MI”},

New Radnik{ImeRadnika = “Stojan”, Radionica = “ML”},

New Radnik{ImeRadnika = “Marko”, Radionica = “MB”},

New Radnik{ImeRadnika = “Mirko”, Radionica = “MO”},

New Radnik{ImeRadnika = “Rajko”, Radionica = “MB”},

New Radnik{ImeRadnika = “Aca”, Radionica = “MM”},

New Radnik{ImeRadnika = “Toma”, Radionica = “MB”},

New Radnik{ImeRadnika = “Sinisa”, Radionica = “MO”},

}

var grups = from p in Radniks

group p bz p.Radionica into g

select new{GroupImeRadnika = g.Key, Members = g};

foreach (var g in groups)

17

Page 18: Seminarski Rad OOP

{

Console.WriteLine (“Radnik iz radionice {0}”, g.GroupImeRadnika);

Foreach (var member in g.Members)

{

Console.WriteLine (“---{0}”, member.ImeRadnika);

}

}

}

}

18