seminarski rad oop
DESCRIPTION
objektno orjentisano programiranjeTRANSCRIPT
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
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
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
{// č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
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
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
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
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
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
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
{
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
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
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
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
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
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
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
{
Console.WriteLine (“Radnik iz radionice {0}”, g.GroupImeRadnika);
Foreach (var member in g.Members)
{
Console.WriteLine (“---{0}”, member.ImeRadnika);
}
}
}
}
18