Click here to load reader

Objektno usmjereno programiranje na slovenskom

  • View
    66

  • Download
    3

Embed Size (px)

DESCRIPTION

Uvod u osnove OOP na slovenskom. Osnove objektrno usmjerenog programiranja.

Text of Objektno usmjereno programiranje na slovenskom

Programski jezik C#

Osnove objektnega programiranjaGregor Jere, Matija Lokar in Sreo Urani

V 0.9 marec 2009

C# . NET

2

Programiranje 1 VS Informatika

C# . NET

3

Programiranje 1 VS Informatika

C# . NET

4

PredgovorOmenjeno gradivo pokriva osnove objektnega programiranja v C# . Gradivo vsekakor ni dokonano in predstavlja delovno razliico. V njem so zagotovo napake (upava, da immanj), za katere se vnaprej opraviujeva. Da bo laje spremljati spremembe, obstaja razdelek Zgodovina sprememb, kamor bova vpisovala spremembe med eno in drugo razliico. Tako bo nekomu, ki si je prenesel starejo razliico, laje ugotoviti, kaj je bilo v novi razliici spremenjeno.

Gregor Jere, Matija Lokar in Sreo Urani Kranj, november 2008

Programiranje 1 VS Informatika

C# . NET

5

Zgodovina sprememb14. 11. 2008: Razliica V0.8 le prenos (e neurejeno) Matijevega, Gregorjevega (str. 1 120) in Saovega gradiva. Premisliti je e potrebno kaj in kako. 5. 3. 2009: Razliica V0.9 e vedno povsem neurejeno. Dodano nekaj gradiva, ki ga je smiselno vkomponirati. Gradivo dodano na konec in sicer: Vsebina prosojnic, ki naj bi bile spredavane letos Zgled za Avto Gradivo, ki pokriva uvod v OOP iz C++. Tam je nekaj smiselnih zgledov, ki pa jih je potrebno prepisati v C#.

Programiranje 1 VS Informatika

C# . NET

6

KAZALOObjektno programiranje ...................................................................................................................................... 9 Motivacija ....................................................................................................................................................... 9 Objektno usmerjeno programiranje kaj je to .............................................................................................. 10 Objekti........................................................................................................................................................... 11 Objekti........................................................................................................................................................... 13 Programiranje v C# ....................................................................................................................................... 14 Objekti........................................................................................................................................................... 14 Klasino/objektno programiranje .................................................................................................................. 14 Od kje razredi? .............................................................................................................................................. 15 Objekt in ime spremenljivke ......................................................................................................................... 15 Ustvarjanje objektov ..................................................................................................................................... 15 C# in objekti .................................................................................................................................................. 15 Ustvarjanje objektov ..................................................................................................................................... 16 Zgled ............................................................................................................................................................. 16 Objektno programiranje ................................................................................................................................ 18 Objekti, razredi, ... ............................................................................................................................................ 19 Zdruevanje podatkov ................................................................................................................................... 19 Uporaba razreda Zajec .................................................................................................................................. 21 Dostop do podatkov v objektu ...................................................................................................................... 22 e en primer - Ulomek .................................................................................................................................. 25 Povzetek ........................................................................................................................................................ 26 Konstruktorji ................................................................................................................................................. 26 this ................................................................................................................................................................. 27 Uporaba razreda: ........................................................................................................................................... 28 Privzeti konstruktor ....................................................................................................................................... 28 Ve konstruktorjev ........................................................................................................................................ 29 Preobteene metode ...................................................................................................................................... 29 Konstruktorji razreda Zajec navzkrino sklicevanje .................................................................................. 30 e malo o this ................................................................................................................................................ 30 Zgled ............................................................................................................................................................. 31 Objektne metode ........................................................................................................................................... 34 Zgledi ................................................................................................................................................................ 37 Datum............................................................................................................................................................ 37 Fibonaccijevo zaporedje................................................................................................................................ 38 Vaje ................................................................................................................................................................... 40 Kochova rta ................................................................................................................................................. 40 Razred Toka in Kochova rta ...................................................................................................................... 40 Ulomek .......................................................................................................................................................... 40 Razred Majica ............................................................................................................................................... 40 Razred Zajec ................................................................................................................................................. 41 Razred Kolega ............................................................................................................................................... 41 Uporaba razreda Kolega ................................................................................................................................ 41 Uporaba razreda Zajec .................................................................................................................................. 42 Datum............................................................................................................................................................ 42 Zajci z datumom............................................................................................................................................ 42 Uporaba razreda Zajec z datumom ................................................................................................................ 42 Nadgradimo datum ........................................................................................................................................ 42 Dostop do stanj objekta..................................................................................................................................... 42 Dostopi do stanj ............................................................................................................................................ 43 Zgledi ............................................................................................................................................................ 48 Programiranje 1 VS Informatika

C# . NET

7

Dostop do stanj/lastnosti ............................................................................................................................... 48 Nastavitve podatkov (stanj)........................................................................................................................... 49 Dostop do stanj.............................................................................................................................................. 51 Ostale metode................................................................................................................................................ 52 Metoda ToString ........................................................................................................................................... 52 Celotni razred Zajec ...................................................................................................................................... 54 Gradnja razredov - zgled .................................................................................................................................. 58 Ustvarjanje objektov ..................................................................................................................................... 58 Problem Banke Butale .................................................................................................................................. 58 Okostje razreda ............................................................................................................................................. 59 Razred Kovanec ............................................................................................................................................ 59 Uporaba razreda Kovanec ............................................................................................................................. 61 Zgled - razred Kvader ................................................................................................................................... 62 Ustvarjanje razredov in objektov: povzetek .................................................................................................. 66 Zgledi ................................................................................................................................................................ 67 Vaje ................................................................................................................................................................... 72 Razred Kolega ............................................................................................................................................... 74 Datum............................................................................................................................................................ 76 Oseba............................................................................................................................................................. 76 Majica ........................................................................................................................................................... 77 Kandidat za direktorja banke ........................................................................................................................ 77 Denarnica ...................................................................................................................................................... 79 Podatkovni nosilec ........................................................................................................................................ 80 Razred Zajec ................................................................................................................................................. 80 Statino in objektno ........................................................................................................................................... 87 Statine komponente ..................................................................................................................................... 87 Statine spremenljivke .................................................................................................................................. 87 Uporaba statinih spremenljivk ..................................................................................................................... 88 Statine komponente dostop ...................................................................................................................... 88 Statine komponente naslavljanje .............................................................................................................. 88 Zajec.............................................................................................................................................................. 88 Statine metode ............................................................................................................................................. 95 Statine metode ............................................................................................................................................. 96 Privatne metode............................................................................................................................................. 97 Dedovanje ......................................................................................................................................................... 97 Pogosto uporabljani postopki I...................................................................................................................... 97 Dedovanje ..................................................................................................................................................... 98 Razred BoljsiUlomek .................................................................................................................................... 98 Uporaba Boljega ulomka ............................................................................................................................. 98 Pogosto uporabljani postopki ........................................................................................................................ 99 Dedovanje ..................................................................................................................................................... 99 Dedovanje ................................................................................................................................................... 100 Iz muhe slon ................................................................................................................................................ 106 Osnova: razred ZajecNov ............................................................................................................................ 106 Prekrite metode ........................................................................................................................................... 106 "Umazane" podrobnosti .............................................................................................................................. 106 Uporaba ....................................................................................................................................................... 106 Zgledi .............................................................................................................................................................. 107 Vaje ................................................................................................................................................................. 107 Zival ............................................................................................................................................................ 107 Razred Pes ................................................................................................................................................... 109 Razred Dalmatinec ...................................................................................................................................... 109 Naloge brez raunalnika .............................................................................................................................. 110 Razred Pes II ............................................................................................................................................... 111 Zajec iz ivali .............................................................................................................................................. 113 Programiranje 1 VS Informatika

C# . NET

8

Embi d.o.o ................................................................................................................................................... 113 Vaje "pe" ................................................................................................................................................... 114 Halo Kitajc .................................................................................................................................................. 118 Trojiko ....................................................................................................................................................... 119 Redki vektorji.............................................................................................................................................. 119 Plavalec ....................................................................................................................................................... 120 Plavalec II ................................................................................................................................................... 121 Razredi in objekti (osnove) ............................................................................................................................... 121 Razred - class .................................................................................................................................................. 122 Enkapsulacija .............................................................................................................................................. 122 Konstruktor ................................................................................................................................................. 127 Preobloeni (overloaded) konstruktorji ....................................................................................................... 129 Kopirni (copy) konstruktorji ....................................................................................................................... 130 Statini (static) konstruktorji ....................................................................................................................... 130 Polja tipa readonly ...................................................................................................................................... 131 Destruktorji ................................................................................................................................................. 131 Lastnost (Property) ...................................................................................................................................... 134 Statine metode ........................................................................................................................................... 137 Statina polja ............................................................................................................................................... 137 Dedovanje (Inheritance) izpeljani razredi ................................................................................................... 139 Kaj je to dedovanje ..................................................................................................................................... 139 Bazini razredi in izpeljani razredi.............................................................................................................. 139 Klic konstruktorja bazinega razreda .......................................................................................................... 140 Doloanje oz. prirejanje razredov ............................................................................................................... 140 Nove metode ............................................................................................................................................... 141 Virtualne metode ......................................................................................................................................... 143 Prekrivne (Override) metode ...................................................................................................................... 143 Polimorfizem - mnogolinost .......................................................................................................................... 146 Uporaba oznaevalca protected ..................................................................................................................... 148 Prosojnice M. Lokar 2009 ................................................................................................................................ 149 Razred Avto ....................................................................................................................................................... 149 Testiranje razreda ........................................................................................................................................... 221 OOP v C++ (avtor dr. M. Krana)................................................................................................................... 221

Programiranje 1 VS Informatika

C# . NET

9

Objektno programiranjeMotivacija Pri programiranju se je izkazalo, da je zelo koristno, e podatke in postopke nad njimi zdruujemo v celote, ki jih imenujemo objekte. Programiranje je potem sestavljeno iz tega, da objekte ustvarimo in jim naroamo, da izvedejo doloene postopke. Veina sodobnih programskih jezikov je objektno ali kot tudi reemo predmetno usmerjenih. Pri uporabi tovrstnih jezikov hitro naletimo naletimo na pojme kot so zdruevanje (enkapsulacija), velinost (polimorfizem), dedovanje (inheritenca), ki so vsaj na prvi pogled zelo zapleteni, Nas ne bodo zanimali, kot tudi ne tevilne druge podrobnosti. Objektno usmerjeno programiranje nam omogoa, da na problem gledamo kot na mnoico objektov, ki med seboj sodelujejo in vplivajo drug na drugega. Na ta nain laje piemo sodobne programe, kjer se nenehno odvija veliko tevilo dogodkov kot so premikanje mike, zapiranje oken, klikanje na gumbe, potrditev doloenih izbir, ki se med sabo prepletajo, vplivajo drug na drugega in kar bi le s teavo sprogramirali na klasien nain z nizanjem zaporedja stavkov in ukazov. tevilni jeziki (JavaScript, Visual Basic for Applications, Java, C#, Python, ) nudijo okolja v katerih so e doloeni objekti, nad katerimi lahko izvajamo doloene metode, funkcije. Tako "iz ni" dobimo grafini objekt g, na katerim potem z doloeno metodo nariemo krog. Ko program zaenemo, ta samodejno ustvari okno z doloenim imenom in gumbom za zapiranje Veina jezikov omogoa, da program zlahka dopolnimo z gumbi, potrditvenimi stikali in podobnimi elementi. Vse to so objekti, ki imajo lastnosti in metode, s katerimi na te objekte vplivamo. Na primer v jeziku JavaScript. Zanima nas le oznaeni delvar i = 0; function animacija() { i = i + 1; if (i == 6) i = 1; document.menjajocaSlika.src = "album" + i + ".jpg"; setTimeout("animacija()", 1000) }

JavaScript spletno stran, na kateri se nahaja, imenuje kot objekt z imenom document. Na tem objektu imamo tudi druge objekte, v naem konkretnem primeru sliko (vstavljeno v jeziku HTML z znako IMG), poimenovano kot menjajocaSlika:

S pomojo stavkov v jeziku JavaScript vplivamo na ta objekt (document.menjajocaSlika) tako, da mu spremenimo lastnost src, kjer je zapisana datoteka, ki naj jo ta objekt prikazujedocument.menjajocaSlika.src = "album" + i + ".jpg";

Podobno z metodo writeln vstavimo v samo dototeko ustrezno kodo v jeziku html. e v kodi spletne strani pie document.writeln("To naj se pojavi na spletni strani!");

pomeni, da naj se objekt document (kar pomeni kar ta spletna stran) spremeni tako, da vsebuje tekst, zapisan med narekovaji. Dejansko je torej uinek isti, kot e bi na spletni strani napisali karTo naj se pojavi na spletni strani!

Seveda pa smo se doslej nauili e dovolj, da vemo, kakne vse monosti s tem imamo verjetno bomo JavaScript uporabili, da bomo napisali na spletno stran kaj bolj zapletenega, na primer besedilo, ki ga bomo prej s pomojo ustreznega postopka obdelali. Tako smo na primer pri esti nalogi hitrega testa v uvodu uporabili monost pisanja na spletno stran zato, da smo na enostaven nain poenotili vse naslove na spletni strani. Programiranje 1 VS Informatika

C# . NET

10

Ko torej piemo programe, imamo s samim izvajalnim okoljem ponavadi na voljo bogato zbirko razlinih objektov (natanneje nartov za to, kakni so objekti doloene vrste). Ni nam potrebno pisati na stotine vrstic kode le za to, da bi dosegli, da na program uporabniku omogoa vnos datuma preko posebnega okna z e izpisanim koledarjem. Vedeti je potrebno le, da imamo v izvajalnem okolju e na voljo (nart za) tovrstni objekt. Ostane nam le e, da tak objekt ustvarimo in s pripravljenimi metodami nanj vplivamo. Tako s spodnjim zgledom v programskem jeziku Java ustvarimo okno z vnosno povrino, po kateri lahko piemo.

e ne bi imeli na voljo e ustreznih objektov, bi na program sestavljalo na desetine ali celo stotine ustreznih ukazov. Tako pa le uporabimo dana narta za objekta JFrame in JTextArea, z ukazom new ustvarimo objekta ustrezne vrste in z metodami, kot so setSize, show in drugimi vplivamo nanju.import javax.swing.*; import java.awt.*; public class JFrameTest { public static void main(String[] args) { JFrame okno = new JFrame("Moje okno"); okno.setSize(250, 250); okno.setLocation(300,200); okno.getContentPane().add(BorderLayout.CENTER, new JTextArea(10, 40)); okno.show(); } }

In seveda imamo na voljo take objekte tudi v standardnih knjinicah jezika C#. Objektno usmerjeno programiranje nam omogoa, da na problem gledamo kot na mnoico objektov, ki med seboj sodelujejo in vplivajo drug na drugega. Za nas je pomembno to, da veina sodobnih jezikov prinaa v svojem izvajalnem okolje celo vrsto e pripravljenih objektov in metod za delo z njimi. Ti objekti so na primer spletna stran, slika na spletni strani, izbire v menuju programov v okolju Microsoft Office, grafino okno, tiskalnik, . S pripravljenimi metodami potem vplivamo na te objekte na primer zamenjamo sliko na spletni strani, spremenimo privzeto delovanje ukaza Print v izbiri File, na grafino povrino nariemo krog, Objektno usmerjeno programiranje kaj je to Pri objektno (ali kot tudi reemo predmetno) usmerjenem programiranju se ukvarjamo z objekti seveda. Objekt je nekakna rna katla, ki dobiva in poilja sporoila. V tej rni katli (objektu) se skriva tako koda (torej zaporedje programskih stavkov), kot tudi podatki (informacije nad katerimi se izvaja koda). Pri klasinem programiranju imamo kodo in podatke loene. Tudi mi smo do sedaj programirali ve ali manj na klasien nain. Pisali smo metode, ki smo jim podatke posredovali preko parametrov. Parametri in metode niso bile prav ni tesno povezane. e smo npr. napisali metodo, ki je na primer poiskala najveji element v tabeli tevil, tabela in metoda nista bili zdrueni tabela ni ni vedela o tem, da naj bi kdo npr. po njej iskal najveja tevila. V objektno usmerjenem (vasih boste sreali tudi kratico OO ali O-O, kar izvira iz object oriented) programiranju pa sta koda in podatki zdueni v nedeljivo celoto objekt. To prinaa doloene prednosti. Ko uporabljamo objekte nam nikoli ni potrebno pogledati v sam objekt. To je dejansko prvo pravilo OO programiranja uporabniku ni nikoli potrebno vedeti, kaj se dogaja znotraj objekta.

Programiranje 1 VS Informatika

C# . NET

11

Objekt Zakaj ni potrebno vedeti tega? Vsi objekti med samo komunicirajo preko sporoil. Za vsak objekt se tono ve, kakna sporoila lahko sprejme in kakna lahko polje. Vse, kar objekt zna narediti, je doloeno z vmesnikom objekta. Se vam zdi to zapleteno? No, pa povejmo malo bolj "po domae". Gre dejansko zato, da nad objektom izvajamo razline metode. In za vsak objekt se tono ve, katere metode zanj obstajajo in kakne rezultate vraajo. Recimo, da imamo doloen objekt z imenom obj, ki predstavlja doloeno osebo in vemo, da ta objekt lahko povpraamo (mu poljemo sporoilo) o tem, koliko je njegov IQ. To storimo tako, da nad njem izvedemo metodo

obj.KolikoJeIQ()Objekt odgovori s sporoilom (metoda vrne rezultat), ki je neko celo tevilo. Koliko je tvoj IQ ?

92

Tisto, kar je pomembno, je to, da nam, kot uporabnikom objekta, ni potrebno vedeti, kako objekt izrauna IQ (je to podatek, ki je zapisan nekje v objektu, je to rezultat nekega preraunavanja ). Kot uporabnikom nam je vano le, da se z objektom lahko pogovarjamo o njegovem IQ. Vse "umazane podrobnosti" o tem, kaj je znotraj katle, je prepueno tistim, ki napiejo kodo s pomojo katere se ustvari objekt in (e je zadeva seveda sprogramirana prav) uporabnik (programer, ki pie drug program, ki te objekte uporablja) se vanje ne more vtikati. Seveda se lahko zgodi, da se kasneje ugotovi, da je potrebno "preurediti notranjost objekta". In tu se izkae prednost OO koncepta. Ker v programih, kjer objekte uporabljamo, ni ne vemo o tem, kaj je znotraj katle, kaj se na primer dogaja, ko objekt povpraamo po IQ, bodo programi navkljub spremembam znotraj katle e vedno delovali. e torej na objekte gledamo kot na rne katle (zakaj rne zato, da se ne vidi, kaj je znotraj!) in z njimi ravnamo le preko sporoil (preko klicev metod), nai programi delujejo ne glede na morebitne spremembe v samih objektih. Omogoanje dostopa do objekta samo preko sporoil in onemogoanje uporabnikom, da vidijo (in brskajo) po podrobnostih, se imenuje skrivanje informacij (information hidding) ali e bolj ueno enkapsulacija (encapuslation). In zakaj je to pomembno? Velja namre, da se programi ves as spreminjajo. Velika veina programov se dandanes ne napie na novo, ampak se spremeni obstoje program. In veina napak izhaja iz tega, da nekdo spremeni doloen delek kode, ta pa potem povzroi, da drug del programa ne deluje ve. e pa so tisti delki varno zapakirani v kapsule, se spremembe znotraj kapsule ostalega sistema prav ni ne tiejo. Objekti Objekt je skupek podatkov, s katerim elimo upravljati kot s celoto. Ima: Podatke: kaj o objektu vemo, kakne podatke o objektu hranimo Metode: Kaj objekt zna Kakne metode lahko izvajamo nad njem Vsak objekt pripada nekemu razredu. e pripada objekt x razredu R, potem pravimo tudi da je x objekt tipa R.

Programiranje 1 VS Informatika

C# . NET

12

Pravzaprav smo se e ves as ukvarjali z objekti, saj smo v naih programih uporabljali razline objekte, ki so e pripravljeni v standardnih knjinicah jezika C#. Oglejmo si nekaj primerov objektov iz standardne knjinice jezika: Objekt tipa StreamReader predstavlja vhodni kanal. Kadar elimo brati s tipkovnice ali z datoteke, naredimo tak objekt in kliemo njegovo metodo readLine za branje ene vrstice. Objekt System.Console predstavlja standardni izhod. Kadar elimo kaj izpisati na zaslon, pokliemo metodo Write na objektu System.Console. Objekt tipa Random predstavlja generator nakljunih tevil. Metoda Next(a, b), ki jo izvedemo nad objektom tega tipa pa nam vrne neko nakljuno celo tevilo med a in b.

StreamWriter pisanje = new StreamWriter(datoteka); //kreiranje objekta StreamWriter pisanje.Flush(); //uporaba metode objekta new Random().Next(1,100); //uporaba metode na objektu iz razreda Random Console.WriteLine(); //uporaba metode WriteLine na objektu Console

Nauili smo se torej uporabnosti objektnega programiranja, nismo pa se e nauili izdelave svojih razredov. In e se vrnemo na razlago v uvodu kot uporabniki isto ni ne vemo (in nas pravzaprav ne zanima), kako metoda Next doloi nakljuno tevilo. In tudi, e se bo kasneje "katla" Random spremenila in bo metoda Next delovala na drug nain, to ne bo "prizadelo" programov, kjer smo objekte razreda Random uporabljali. Seveda, e bo sporoilni sistem ostal enak. V omenjenem primeru to pomeni, da se bo metoda e vedno imenovala Next, da bo imela dva parametra, ki bosta doloala meje za nakljuna tevila in da bo odgovor (povratno sporoilo) neko nakljuno tevilo z elenega intervala. Seveda pa nismo omenjeni le na to, da bi le uporabljali te "rne katle", kot jih pripravi kdo drug (npr. jih dobimo v standardni knjinici jezika). Objekti so uporabni predvsem zato, ker lahko programer definira nove razrede in objekte, torej sam ustvarja te nove rne katle, ki jih potem on sam in drugi uporablja. Oglejmo si primer programa v C#, ki uporablja objekte, ki jih napiemo sami.

PRVI1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:

OBJEKTNI PROGRAM

using System; public class MojR { private string mojNiz; public MojR(string nekNiz) { mojNiz = nekNiz; } public void Izpisi() { Console.WriteLine(mojNiz); } } public class Pozdrav { public static void Main(string[] arg) { MojR prvi = new MojR("Pozdravljen, moj prvi objekt v C#!"); prvi.Izpisi(); } }

Programiranje 1 VS Informatika

C# . NET

13

Program napiimo kar na obiajni nain v okolju SharpDevelop torej New Solution/Windows Applications/Console Application. Vnesene vrstice kar vse pobriimo in napiimo zgornjo kodo. Ko program prevedemo in poenemo, dobimo

Na kratko razloimo, "kaj smo se li". V vrsticah 3 13 smo definirali nov razred z imenom MojR. Ta je tak, da o vsakem objektu te vrste poznamo nek niz, ki ga hranimo v njem (vrstica 4). Vse znanje, ki ga objekti tega razreda imajo, je, da se znajo odzvati ne metodo Izpis(), ko izpiejo svojo vsebino (torej niz, ki ga hranimo v njem). V vrsicah 15 20 je na "pravi program", torej tisti del reitve, ki opravi dejansko neko delo. V vrstici 17 naredimo primerek objekta iz razreda MojR in vanj shranimo niz "Pozdravljen, moj prvi objekt v C#!". V vrstici 18 pa temu objektu naroimo, naj izpie svojo vsebino.

Objekti o stanja: Programiranje 1 VS Informatika

C# . NET

14

o o

o

Lastnosti, podatki, komponente znanje Odzivanje na dogodke Zdrueno v celoto Podatki in metode, ki opisujejo neko stvar/objekt oga: Podatki: velikost, barva, poloaj v prostoru, Metode: sprememba velikosti, sprememba poloaja, Ulomek: Podatki: tevec, imenovalec Metode: spremeni tevec, spremeni imenovalec, setej, obratna vrednost, lepo izpii, ... Razlika med ogo kot idejo oge in mojo ogo (konkretni primerek realizacija ideje oge) oziroma med ulomkom kar tako in ulomkom .

Programiranje v C# Sestavljanje razredov: Opis lastnosti objektov Opis metod (znanja objektov): Ustvarjanje objektov in njihova uporaba "Ukazovanje" objektom, kaj naj ponejo Objekt za izpolnitev doloene naloge potrebuje druge objekte in njihove metode Zaetek: Glavni razred (ki ima metodo Main) Izvajanje metode Main ustvarjanje objektov, proenje dogodkov, odzivanje na dogodke,

Razred je abstraktna definicija objekta in e elimo nek razred uporabiti, mora obiajno obstajati vsaj en primerek razreda. Primerek nekega razreda imenujemo objekt. Ustvarimo ga s kljuno besedo new. ImeRazreda primerek = new ImeRazreda(); Objekt je raunalniki model predmeta ali stvari iz vsakdanjega ivljenja (avto, oseba, datum). Za reitev problema uvedemo mnoico objektov, ki si medsebojno poiljajo sporoila. Lastnosti objektov so zapisane v razredih (class), ki vsebujejo:

podatke in , metode oz. odzive objektov na sporoila.

Stanje objekta opiemo s spremenljivkami, njihovo obnaanje oz. odzive pa z metodami. Objekti Objekt je kakrenkoli skupek podatkov, s katerimi elimo upravljati. Osnovni pristop objektnega programiranja: objekt = podatki + metode za delo s podatki. Ko elimo kak podatek (objekt) obdelati, objektu (podatku) signaliziramo, kaj naj se zgodi: Pokliemo ustrezno metodo v objektu. Objekt je "rna katla, ki sprejema in poilja sporoila. Jedro objekta sestavljajo njegove spremenljivke, okrog katerih se nahajajo njegove metode. Klasino/objektno programiranje Klasino programiranje: program = metode Ko elimo kak podatek obdelati v klasinem programiranju: pokliemo ustrezno metodo z argumenti argumenti: podatki, ki naj jih obdela. e elimo izvesti metodo f na podatku x: o Klasino: Programiranje 1 VS Informatika

C# . NET

15

o

izvedi statino metodo f na podatku x f(x); Objektno: podatku/objektu x signaliziraj, da naj izvede metodo f x.f();

Od kje razredi? Veliko razredov je e vgrajenih (so v standardnih knjinicah) v C# in njegovo oklolje. Taki razredi so na primer Math, System, StreamReader, o .NET Framework o C# je .NET jezik ima dostop do vseh razredov, definiranih v knjinicah (zbirkah razredov) okolja .NET Glej npr. http://msdn2.microsoft.com/sl-si/library/ms229335(en-us).aspx

Razporejeni v imenske prostore System, System.IO

Razrede lahko dobimo tudi iz drugih virov: o Nai stari razredi o Drugi programerji

Potrebujemo dostop do ustrezne datoteke (dll, exe) Objekt in ime spremenljivke

NekiObjekt a; a je naslov, kjer bo objekt (referenca na objekt) V pomnilniku se je naredil objekt tipa NekiObjekt() / po pravilih, ki so doloena z opisom razreda NekiObjekt V pomnilniku se je naredil objekt tipa NekiObjekt() in a kae na ta novo ustvarjeni objekt

new NekiObjekt(); a = new NekiObjekt(); Ustvarjanje objektov Razred je ablona, ki definira spremenljivke in metode skupne vsem objektom iste vrste. class: Nart objekta, ablona Primerek razreda (instanca) konkretni objekt: Ustvarimo ga z new Brez tega objekta NE MOREMO uporabiti NekiObjekt a; Objekt NE obstaja a je IME objekta natanneje a je ime spremenljivke, kjer hranimo NASLOV objekta vrste NekiObjekt C# in objekti Razred (class) je opis vrste objekta (nart, kako naj bo objekt videti) opis ideje objekta. Primerek razreda (instanca) konkretni objekt.

Programiranje 1 VS Informatika

C# . NET

16

Ustvarjanje objektov

Ulomek ime = new Ulomek(3, 4);Reemo: V objektu ime je shranjen ulomek ; Toneje: v spremenljivki ime je naslov nekega objekta tipa Ulomek, ki predstavlja ulomek . Spremenljivka ime kae na objekt tipa Ulomek, ki Prvi ukaz je dejansko spoj dveh stavkov: deklaracija in prireditev

Ulomek ime; ime = new Ulomek(3, 4);ime: _2h11b11__ 2h11b11: Brez new objekta e NI vasih skrito Nizi string a = "bla"; string a = new string("bla"); Tabele int[] tabela = {1, 2, 3}; int[] tabela = new int[3]; tabela[0] = 1;

o o

Zgled Poglejmo si e en zgled. Denimo, da bi radi napisali program, ki bo prebral nek ulomek in mu pritel 1/2. "Klasino" se bomo tega lotili takole (seveda pisec ni pozabil, kako se setevajo ulomki, a takojle, po Janezkovo, si je laje zapomniti ;-) )

POVEAJMO1: 2: 3: 4: 5: 6:

ULOMEK KLASINO

using System; namespace UlomkiKlasika { class Program { public static void Main(string[] args) {Programiranje 1 VS Informatika

C# . NET

17

7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:

// vnos podatkov Console.Write("tevec ulomka: "); string beri = Console.ReadLine(); int stevec = int.Parse(beri); Console.Write("Imenovalec ulomka: "); beri = Console.ReadLine(); int imenovalec = int.Parse(beri); // "delo" stevec = stevec + 1; imenovalec = imenovalec + 2; // izpis Console.WriteLine("Nov ulomek je: " + stevec imenovalec); Console.Write("Press any key to continue . . . "); Console.ReadKey(true); } } }

+

"

/

"

+

Sedaj pa to naredimo e "objektno". Oitno bomo potrebovali razred Ulomek. Objekt tipa Ulomek hrani podatke o svojem tevcu in imenovalcu. Njegovo znanje je, da "se zna" poveati za drug ulomek. To pomeni, da vsebuje metodo, ki ta ulomek povea za drug ulomek. Shematsko bo program (kjer so doloeni deli skriti) videti kot

Cel program pa bo:

POVEAJMO

ULOMEK

-

OBJEKTNO

24: using System; 25: namespace UlomkiObjektno 26: { 27: class Ulomek { 28: public int stevec; 29: public int imenovalec; 30:Programiranje 1 VS Informatika

C# . NET

18

31: public Ulomek(int st, int im) { 32: this.stevec = st; 33: this.imenovalec = im; 34: } 35: 36: public void Pristej(Ulomek a) { 37: this.stevec = this.stevec + a.stevec; 38: this.imenovalec = this.imenovalec + a.imenovalec; 39: } 40: } 41: class Program 42: { 43: public static void Main(string[] args) 44: { 45: // vnos podatkov 46: Console.Write("tevec ulomka: "); 47: string beri = Console.ReadLine(); 48: int stevec = int.Parse(beri); 49: Console.Write("Imenovalec ulomka: "); 50: beri = Console.ReadLine(); 51: int imenovalec = int.Parse(beri); 52: Ulomek moj = new Ulomek(stevec, imenovalec); 53: // "delo" 54: Ulomek polovica = new Ulomek(1, 2); 55: moj.pristej(polovica); 56: // izpis 57: Console.WriteLine("Nov ulomek je: " + moj.stevec + " / " + 58: moj.imenovalec); 59: } 60: } 61: }e posebej oznaimo kljune toke (poleg definicije razreda Ulomek v vrsticah 4 17):

Objektno programiranje Imamo nek problem. Kako se torej lotiti nartovanja reitve s pomojo objektnega programiranja? Programiranje 1 VS Informatika

C# . NET

19

Z analizo ugotovimo, kakne objekte potrebujemo za reevanje Pregledamo, ali e imamo na voljo ustrezne razrede Standardna knjinica Druge knjinice Nai stari razredi Sestavimo ustrezne manjkajoe razrede Sestavimo glavni program, kjer s pomojo objektov reimo problem

Objekti, razredi, ...Zdruevanje podatkov Denimo, da piemo program, ki bo pomagal upravljati farmo zajcev. Za vsakega zajca poznamo: serijsko tevilko spol teo Kako dosei, da se podatki drijo skupaj: Tabela ni ustrezna Tabela je zbirka istovrstnih podatkov Pri tabelah smo omenili, da so sestavljen podatkovni tip. Vsebujejo elemente istega tipa. Velikokrat pa elimo ustvariti tip, ki je prav tako sestavljen, a iz razlinih podatkovnih tipov. V ta namen imamo v jeziku C# tako imenovane strukture. A ker gre v bistvu le za posebni primer objektov, jih bomo kar preskoili in si raji kar neposredno ogledali objekte. Da pa boste vedeli zakaj gre, e boste v kaknem programu naleteli na kljuno besedo struct, si zapomnimo le, da gre za nekakne "poenostavljene" objekte. Sestavimo razred Zajec Opis podatkov, ki sestavljajo poljubnega zajca

V zgledih do sem smo razrede pisali le za "lokalno uporabo", znotraj doloenega programa. Sedaj se nauimo e, kako na najlaji nain gradimo svojo knjinico razredov, ki jih bomo uporabljali v razlinih programih. Na ta nain bomo tudi bolj loili tisti del programiranja, ko gradimo razrede in tisti del, ko uporabljamo objekte doloenega razreda. V okolju SharpDevelop tokrat ne izberemo Windows Applications/Console Application, ampak C# / Class Library

Programiranje 1 VS Informatika

C# . NET

20

Kot ime bomo napisali MojiRazredi. V ta projekt bomo dodajali vse tiste razrede, ki jih bomo ustvarjali, vkljuno z naim razredom Zajec.

Vidimo, da je SharpDevelop pripravil okolje in naredil tako imenovam imenski prostor MojiRazredi. Znotraj tega imenskega prostora bomo zlagali nae razrede. Ker nam ime MyClass ni ve, bomo to spremenili v Zajec. Omenimo e komentarje, ki se zano z ///. To so tako imenovani dokumentacijski komentarji. Ti sluijo za to, da pripravimo dokumentacijo o razredu. Ta je zelo pomembna, saj nosi tisto informacijo, ki jo kasneje potrebujemo, e elimo razred uporabljati. Zanekrat si zapomnimo le, da na ustrezno mesto napiemo kratek povzetek o tem, emu je razred namenjen. Ve o tem si lahko preberete: http://www.softsteel.co.uk/tutorials/cSharp/lesson19.html http://www.winnershtriangle.com/w/Articles.XMLCommentsInCSharp.asp http://www.csharphelp.com/archives3/archive598.html ...

RAZRED ZAJEC21: public class Zajec { 22: public string serijska; 23: public bool spol; 24: public double masa; 25: }

Programiranje 1 VS Informatika

C# . NET

21

S tem imamo napisan opis, kako je doloen poljuben zajec: Nart, kakni so zajci Ni to konkreten zajec Ni metode Main, dejansko se NI ne izvede, ... Ni namenjeno poganjanju kot program. Zato bo stvar potrebno prevesti drugae. V Build izberemo Build Moji Razredi (oziroma pritisnemo na F9). S tem smo ustvarili ustrezno prevedeno obliko in sicer MojiRazredi.dll. TA vsebuje med drugim tudi definicijo razreda Zajec. Uporaba razreda Zajec Denimo, da sedaj piemo nek program, kjer bomo potrebovali Zajce. V ta namen sedaj sestavimo program v C#. Obnaamo se tako kot smo pisali programe do sedaj. v SharpDevelop: File/New Solution/Winows applications/Console Application Sedaj moramo dodati e t.i. referenco, da bo na program prepoznal na razred. Project / Add reference

Programiranje 1 VS Informatika

C# . NET

22

V oknu, ki se odpre, izberemo .Net Assembly Browser. Poiemo imenik MojiRazredi/bin/Debug in v njem datoteko MojiRazredi.dll.

Da bomo kraje pisali, dodamo sedaj imenski prostor MojiRazredi (ker vsebuje definicijo razreda Zajec)

using MojiRazredi;e sedaj v programu potrebujemo konkretnega zajca, ga ustvarimo z new: new Zajec() Ustvaril se je konkreten zajec po navodilih za razred Zajec (ta zajec ima torej tri podatke / lastnosti / komponente) Metoda je vrnila naslov, kje ta konkretni zajec je Zajec rjavko = new Zajec(); V spremenljivki rjavko je naslov, kje je novo ustvarjeni zajec (objekt) Dostop do podatkov v objektu rjavko.spol = true; rjavko.serijska = BRGH_17_A; rjavko.masa = 3.2;

UPORABA

RAZREDA

ZAJEC

26: using System; 27: using MojiRazredi; 62:Programiranje 1 VS Informatika

C# . NET

23

63: namespace TestZajec 64: { 65: class Program 66: { 67: public static void Main(string[] args) 68: { 69: Zajec z1 = new Zajec(); 70: z1.serijska = "1238-12-0"; 71: z1.spol = false; 72: z1.masa = 0.12; 73: z1.masa = z1.masa + 0.3; 74: Console.WriteLine("Zajec ima ser. t.:" + z1.serijska); 75: 76: Console.Write("Press any key to continue . . . "); 77: Console.ReadKey(true); 78: } 79: } 80: }

FARMAZAJCEV28: public class FarmaZajcev { 29: public static void Main(atring[] ar) { 30: Zajec[] zajci = new Zajec[10]; // na farmi imamo do 10 zajcev 31: int i = 0; 32: while (i < 10) { 33: zajci[i] = new Zajec(); // rodil se je nov zajec 34: zajci[i].serijska = "1238-12- + i; 35: zajci[i].spol = false; 36: zajci[i].masa = 0.12; 37: i++; 38: } 39: ... 40: } 41: }

Programiranje 1 VS Informatika

C# . NET

24

Programiranje 1 VS Informatika

C# . NET

25

e en primer - Ulomek Denimo, da bi potrebovali e podatkovni tip Ulomek. Na projekt MojiRazredi (seveda bi lahko naredili novo knjinico razredov) dopolnimo zRAZRED

ULOMEK

81: public class Ulomek { 82: public int stevec; 83: public int imenovalec; 84: }Potem, ko z Build/Build MojiRazredi prevedemo stvar na novo, je knjinica z novim razredom Ulomek pripravljena za uporabo. To pomeni, da novi razred (e elite novi podatkovni tip) lahko uporabljamo v drugih programih, kot tudi pri sestavljanju drugih razredov. Ne pozabimo e elimo narediti objekt vrste (tipa) Ulomek, napiemo

Ulomek x = new Ulomek();Kako napolniti stevec in imenovalec? x.stevec : spremenljivka tipa int! x.imenovalec : enako

x.stevec = 1; x.imenovalec = x.stevec + 1;Programiranje 1 VS Informatika

C# . NET

26

No, ne pozabimo, da e doloen razred potrebujemo le v sklopu reitev enega primera, ga lahko ustvarimo tudi "lokalno", znotraj tistega programa.

PRIMER42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61:

IZDELAVE IN UPORABE RAZREDA

using System; public class Vozilo { public int letnik; public string proizvajalec; public int prevozeniKilometri; } class Program { public static void Main() { Vozilo mojAvto = new Vozilo();//kreiramo primerek mojAvto.proizvajalec = "Citron"; mojAvto.letnik = 2000; mojAvto.prevozeniKilometri = 90000; Console.WriteLine("Proizvajalec: " + mojAvto.proizvajalec); Console.WriteLine("Letnik: " + mojAvto.letnik); Console.WriteLine("Kilometri: " + mojAvto.prevozeniKilometri); } }

Razlaga. Najprej ustvarimo razred z imenom vozilo (vrstice 2-7). V glavnem programu kreiramo nov primerek (objekt) z imenom mojAvto razreda Vozilo (vrstica 12). Objektu doloimo vrednosti (vrstice 13-15) in izpiemo vrednosti (vrstice 16-18).

Povzetek Najenostavneji razred kreiramo tako, da doloimo spremenljivke, ki doloajo objekte tega razreda. Te so lahko razlinih podatkovnih tipov. Sintaksa najenostavneje definicije razreda je naslednja: public class ImeRazreda { public podatkovni tip element1; public podatkovni tip element2; public podatkovni tip elementn; } e elimo tak razred uporabljati v nekem programu, moramo v programu dodati referenco na ustrezno prevedeno obliko (dll) tega razreda. Objekt tega razreda ustvarimo z new ImeRazreda(); S tem dobimo naslov, kje ta objekt je in ga shranimo v spremenljivko tipa ImeRazreda: ImeRazreda imeObjekta = new ImeRazreda(); Do posameznih spremenljivk (reemo jim tudi komponente ali pa lastnosti), dostopamo z imeObjekta.imeKomponente Konstruktorji Ob tvorbi objekta bi radi nastavili zaetno stanje spremenljivk (in morda opravili e kaj a o tem kasneje). Programiranje 1 VS Informatika

C# . NET

27

V ta namen imamo v C# posebne metode, ki jih imenujemo konstruktorji. Konstruktor je metoda, ki jo pokliemo ob tvorbi objekta z new. Je brez tipa rezultata. To ne smemo zamenjati z metodami, ki rezuultata ne vraajo so tipa void). Konstruktor tipa rezultata sploh nima, tudi void ne. Prav tako smo omenjeni pri izbirri imena te metode. Konstruktor mora imenti ime nujno tako. kot je ime razreda. Najveja omejitev, ki loi konstruktorje od drugih metod pa je ta, da konstruktor ne moremo klicati na poljubnem mestu (kot lahko ostale metode). Kliemo ga izkljuno skupaj z new: Klic: new Zajec(); Razred Zajec

RAZRED ZAJEC

S KONSTRUKTORJEM

85: public class Zajec { 86: public string serijska; 87: public bool spol; 88: public double masa; 89: 90: // konstruktor 91: public Zajec() { 92: this.spol = true; // vsem zajcem na zaetku doloimo m. spol 93: this.masa = 1.0; // in tehtajo 1kg 94: this.serijska = NEDOLOENO; 95: } 96: }this V zgornjem primeru smo v konstruktorju uporabili prijem, ki ga doselj e nismo sreali. Napisali smo this. Kaj to pomeni? this oznauje objekt, ki ga "obdelujemo". V konstruktorju je to objekt, ki ga ustvarjamo. this.spol se torej nanaa na lastnost/komponento spol objekta, ki se ustvarja (ki ga je ravno naredil new). Denimo, da v nekem programu napiemo

Zajec rjavko = new Zajec(); Zajec belko= new Zajec(); Pri prvem klicu se ob uporabi konstruktorja Zajec() this nanaal na rjavko, pri drugem na belko. Na ta nain (z this) se lahko sklicujemo na objekt vedno, kadar piemo metodo, ki jo izvajamo nad nekimobjektom. Denimo, da smo napisali

Random ng = new Random(); Random g2 = new Random(); Console.WriteLine(ng.Next(1,10)); Kako so programerji, ki so sestavljali knjinico in v njej razred Random lahko napisali kodo metode, da se je vedelo, da pri metodi Next mislimo na uporabo generatorja ng in ne na g2? Denimo, da imamo razred MojRazred (v njem pa komponento starost) in v njem metodo MetodaNeka. V programu, kjer razred MojRazred uporabljamo, ustvarimo dva objekta tipa MojRazred. Naj bosta to objA in objC. Kako se znotraj metode MetodaNeka sklicati na ta objekt (objekt, nad katerim je izvajana metoda)? e torej metodo MetodaNeka kliemo nad obema objektoma z objA.MetodaNeka() oziroma zobjC.MetodaNeka(), kako v postopku za metodaNeka povedati, da gre: Prvi za objekt z imenom objA drugi za objekt z imenom objC e se moramo v kodi metode metodaNeka sklicati recimo na komponento starost (jo recimo izpisati na zaslon), kako povedati, da naj se ob klicu objA.MetodaNeka() uporabi starost objekta objA, ob klicu objC.MetodaNeka() pa starost objekta objC?

Console.WriteLine("Starost je: " + ?????.starost);Ob prvem klicu so ???? objA, ob drugem pa objC. To "zamenjavo" doseemo z this. Napiemo

Console.WriteLine("Starost je: " + this.starost);Programiranje 1 VS Informatika

C# . NET

28

Ob prvem klicu this pomeni objA, ob drugem pa objC. Torej v metodi na tistem mestu, kjer potrebujemo konkretni objekt, nad katerim metodo izvajamo, napiemo this. Uporaba razreda: Kot smo povedali e vekrat, je razred le nart, kako so videti objkekti doloenega razreda. e potrebujemo konkreten primer, v naem primeru Zajca, ga ustvarimo z new:

new Zajec()S tem se je ustvaril konkreten zajec (torej tak, ki ima tri spremenjlivke za hranjenje podatkov), nad katerim smo takoj potem izvdeli doloeno akcijo po navodilih iz konstruktorja Zajec(). Kombinacija new Zajec()je torej poskrbela, da ima objekt tipa Zajec tri podatke z vrednostmi, kot je predpisano v konstruktorju. Privzeti konstruktor e konstruktorja ne napiemo (kot ga nismo prej), ga naredi prevajalnik sam (a metoda ne naredi ni). Dokler je bil na razred zajec

RAZRED ZAJEC1: 2: 3: 4: 5: public class Zajec { public string serijska; public bool spol; public double masa; }

je prevajalnik sam dodal privzeti kostruklor.

PRIVZETI

KONSTRUKTOR RAZREDA

ZAJEC

97: public Zajec() { 98: }Kakor hitro pa smo konstruktor Zajec() napisali sami, se seveda prevajalnik ni ve "vmeaval": Ko smo napisaliRAZRED

ULOMEK

99: public class Ulomek { 100: public int stevec; 101: public int imenovalec; 102: }je torej to enako, kot e bi napisaliRAZRED

ULOMEK

S PRIVZETIM KONSTRUKTORJEM

103: public class Ulomek { 104: public int stevec; 105: public int imenovalec; 106: 107: public Ulomek() { 108: } 109: }Konstruktorjev ne moremo klicati posebej (kot ostale metode), ampak le, ko tvorimo objekt z new. Konstruktorje uporabljamo za vzpostavitev zaetnega stanja objekta. Ne pozabimo, da imajo enako ime kot razred. Nimajo tipa rezultata (tudi void ne!). Prat tako ne vsebujejo stavka return.

Programiranje 1 VS Informatika

C# . NET

29

Ve konstruktorjev Uporabniki bi poleg privzetega zajca, radi e monost, da bi takoj, ko zajca naredijo, temu doloili e serijsko tevilko. Radi bi torej konstruktor

public Zajec(string serijskaSt)Poleg tega pa vasih na farmo dobijo tudi poiljko samic. Torej potrebujejo e konstruktor

public Zajec(bool spol)Vasih pa so zajci "nestandardni"

public Zajec(string serijskaSt, bool spol, double teza)Potrebovali bi torej, da ima razred ve konstruktorjev. A ker morajo imeti vsi konstruktorji ime tono tako, kot je ime razreda, to pomeni, da mora biti metoda

public Zajec(string serijskaStev, bool spol, double masa)Ker pa imamo e od prej metodo

public Zajec()to pomeni, da bi imeli ve metod z enakim imenom. Je to sploh mono? Jezik C# podpria tako imenovano preobteevanje (overloading) metod. Tako imamo lahko znotraj istega programa ve metod z enakim imenom. To ne velja le za konstruktorje, ampak tudi v splonem. Metode se morajo razlikovati ne v imenu, ampak podpisu. Podpis metode je sestavljen iz imena metode in tipov vseh parametrov. Konstruktor

Zajec()ima torej podpis enostavno Zajec, konstruktor

public Zajec(string serijskaStev, bool spol, double masa)pa podpis Zajec_string_bool_double Preobteene metode Kot smo omenili, so lahko preobteene tudi navadne metode (ne le konstruktorji). Prav tako enako velja e enkrat preobteenost oznauje monost, da imamo ve enako poimenovanih metod, ki pa sprejemajo parametre razlinega tipa. Zakaj je to uporabno? Denimo, da imamo metodo Ploscina, ki kot parameter dobi objekt iz razreda Kvadrat, Krog ali Pravokotnik. Kako jo zaeti?

public static double Ploscina(X lik)Ker ne vemo, kaj bi napisali za tip parametra, smo napisali kar X. e preobteevanje ne bi bilo mono, bi morali napisati metodo, ki bi sprejela parameter tipa X, kjer je X bodisi Kvadrat, Krog ali Pravokotnik. Seveda to ne gre, saj prevajalnik nima naina, da bi zagotovil, da je X oznaka bodisi za tip Kvadrat, tip Krog ali pa tip Pravokotnik. Pa tudi e bi lo kako bi nadaljevali? V kodi bi morali rei ... e je lik tipa kvadrat, uporabi to formulo, e je lik tipa Krog spet drugo ... S preobteevanjem pa problem reimo enostavno. Napiemo tri metode

public static double Ploscina(Kvadrat lik) { public static double Ploscina(Krog lik) { public static double Ploscina(Pravokotnik lik) { Ker za vsak lik znotraj ustrezne tono vemo, kaken je, tudi ni teav z uporabo pravilne forumule. Imamo torej tri metode, z enakim imenom, a razlinimi podpisi. Seveda bi lahko problem reili brez preobteevanja, recimo takole:

public static double PloscinaKvadrata(Kvadrat lik) { public static double PloscinaKroga(Krog lik) { public static double PloscinaPravokotnika(Pravokotnik lik) { A s stalia uportabnika metod je uporaba preobteenih metod enostavneja. e ima nik lik bla, ki je bodisi tipa Kvadrat, tipa Krog ali pa tipa Pravokotnik, metodo poklie z Ploscina(bla), ne da bi mu bilo potrebno razmiljati, kakno je pravilno ime ustrezne metode ravno za ta lik. Prav tako je enostavneje, e dobimo e

Programiranje 1 VS Informatika

C# . NET

30

etrti tip objekta v glavno kodo ni potrebno posegati naredimo le novo metodo z istim imenom (Ploscina) in s parametrom katerega tip je novi objekt. Klic pa je e vedno Ploscina(bla)! Podpisi metod Podpis metode: Podpis: ime + tevilo in tipi parametrov! Tip rezultata (return tip) NI del podpisa!

public static int NekaMetoda(double x)Podpis metode: public static int NekaMetoda(double x) Podpis: NekaMetoda_double interno ime Kaj je lahko soasno: public static int NekaMetoda() public static int NekaMetoda(double y) public static int NekaMetoda(double x) public static double NekaMetoda(double x) public static int nekaDrugaMetoda(double y) Konstruktorji razreda Zajec navzkrino sklicevanje Poglejmo, kako bi kostruktorje razreda Zajec napisali "zares".

KONSTRUKTORJI62: 63: 64: 65: 66: 67: 68: 69: 70:

RAZREDA

ZAJEC

public Zajec() { this.spol = true; // vsem zajcem na zaetku doloimo m. spol this.masa = 1.0; // in tehtajo 1kg this.serijska = NEDOLOENO; } public Zajec(string serijskaStev) : this() { this.serijska = serijskaStev; }

71: public Zajec(string serijskaStev, 72: bool spol, double masa) : this(serijskaStev) { 73: this.masa = masa; // popravimo maso 74: this.spol = spol; // popravimo spol 75: }Kljuna beseda this v zgornjem zgledu nastopa v dveh vlogah. Enkrat je uporabljena za ime objekta, kar e poznamo (this.spol, this.serijska ), novo pa je uporaba this( takoj za seznamom parametrov nekega konstruktorja. e malo o this o this( Za klic drugega konstruktorja pred vsemi ostalimi stavki drugega konstruktorja this() this() o this. Za dostop do lastnosti this.serijska e ni monosti zamenjave, lahko izpustimo Programiranje 1 VS Informatika

C# . NET

31

serijska this.spol = spol; Obstajalo je e DRUGO ime spol Loiti med spremenljivko spol, ki je parameter in lastnostjo objekta z imenom spol "Prednost" ima bolj "lokalna" stvar torej parameter spol = spol; Zgled Oglejmo si e en primer sestavljanja razredov. Denimo, da bi radi napisali program, ki vodi evidenco o lanih portnega kluba. Podatki o lanu obsegajo ime, priimek, letnico vpisa v klub in vpisno tevilke (seveda je to poenostavljen primer). Torej objekt, ki predstavlja lana kluba, vsebuje tiri podatke:

RAZRED CLAN76: public class Clan { 77: public string ime; 78: public string priimek; 79: public int leto_vpisa; 80: public string vpisna_st; 81: }S tem smo povedali, da je vsak objekt tipa Clan sestavljen iz tirih komponente: ime, priimek, leto_vpisa, vpisna_st. e je a objekt tipa Clan, potem lahko dostopamo do njegove komponente ime tako, da napiemo a.ime. Nov objekt naredimo z ukazom new, kot to kae naslednji primer:

TESTKLUB82: public class TestKlub { 83: public static void Main(string[] args) { 84: 85: Clan a = new Clan(); 86: a.ime = "Janez"; 87: a.priimek = "Starina"; 88: a.leto_vpisa = 2000; 89: a.vpisna_st = "2304"; 90: 91: Clan b = new Clan(); 92: b.ime = "Mojca"; 93: b.priimek = "Mavko"; 94: b.leto_vpisa = 2001; 95: b.vpisna_st = "4377"; 96: 97: Clan c = b; 98: c.ime = "Andreja"; 99: 100: Console.WriteLine("Clan a:\n" + a.ime + " " 101: " " + a.leto_vpisa + " (" 102: 103: Console.WriteLine("Clan b:\n" + b.ime + " " 104: " " + b.leto_vpisa + " (" 105: 106: Console.WriteLine("Clan c:\n" + c.ime + " " 107: " " + c.leto_vpisa + " (" 108: Console.ReadLine(); 109: } 110: }Programiranje 1 VS Informatika

+ a.priimek + + a.vpisna_st + ")\n"); + b.priimek + + b.vpisna_st + ")\n"); + c.priimek + + c.vpisna_st + ")\n");

C# . NET

32

Hm, kako to, da sta dva zadnja izpisa enaka? V programu smo naredili dva nova objekta razreda Clan, ki sta shranjena v spremenljivkah a in b. Kot vedno, se nove objekte naredi z ukazom new. Spremenljivka c pa je isti objekt kot b, se pravi, da se v 16. vrstici ni naredila nova kopija objekta b, ampak se spremenljivki b in c sklicujeta na isti objekt. In zato smo z vrstico 23 vplivali tudi na ime objekta b! V vrsticah 48 smo naredili objekt a in nastavili vrednosti njegovih komponent. Takole nastavljanje je v praksi dokaj neprimerno, ker se zlahka zgodi, da kako komponento pozabimo nastaviti. Zato C# omogoa, da delamo nove objekte na bolj praktien nain s pomojo konstruktorjev. Konstruktor je posebna metoda, ki ima enako ime kot je ime razreda. Konstruktor uporabimo v ukazu new. C# najprej naredi nov objekt, nato pa poklie konstruktor. Znotraj konstruktorja se pravkar narejeni objekt imenuje this. Primer:

111: public class Clan { 112: public string ime; 113: public string priimek; 114: public int leto_vpisa; 115: public string vpisna_st; 116: 117: public Clan(string i, string p, int l, string v) { 118: this.ime = i; 119: this.priimek = p; 120: this.leto_vpisa = l; 121: this.vpisna_st = v; 122: } 123: }Poskusimo ali nae "pacanje" po razredu kaj vpliva na testni program. Ko poskusimo prevesti program, prevajalnik "protestira". Kako, kaj pa tisto govorjenje o tem, da spremembe razreda ne vplivajo na programe, ki razred le uporabljajo. Se je kje spremenilo kaj na nivoju sporoil? Saj jih v prvotnem programu sploh nimamo. Torej se ne bi smelo ni pokvariti! Razlog je v tem, da uporabimo privzeti konstruktor (Clan()), ki ga pa v razredu Clan nismo napisali. Ampak, saj ga prej tudi ni bilo? Kako je pa prej delovalo? Kot smo rekli e prej, e konstruktorja ne napiemo, C# sam doda konstruktor Clan(). Zato je prej zadeva delovala. Kakor hitro pa napiemo poljubni konstruktor, se C# ne vmeava ve. Zato sedaj ni sam dodal konstruktor Clan(), in testni program ne dela ve prav. V ta namen si je dobro zapomniti, da v razredih vedno napiemo tudi konstruktor Clan().

RAZRED CLAN 110: public class Clan { 111: public string ime; 112: public string priimek; 113: public int leto_vpisa; 114: public string vpisna_st; 115: 116: public Clan() {Programiranje 1 VS Informatika

C# . NET

33

117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: }

this.ime = "Ne vem"; this.priimek = "Ne vem"; this.leto_vpisa = 0; this.vpisna_st = "Ne vem"; } public Clan(string i, string p, int l, string v) { this.ime = i; this.priimek = p; this.leto_vpisa = l; this.vpisna_st = v; }

Ko sedaj poskusimo izvesti na testni program, teav ni ve in dobimo isti rezultat. A emu smo potem pisali e drugi konstruktor in zakaj smo se sploh ubadali z njimi, e pa je stvar enaka kot prej. Poglejmo ta testni program

TESTCLAN130: public class TestClan{ 131: public static void Main(string[] args) { 132: Clan a = new Clan("Janez", "Starina", 2000, "2304"); 133: Clan b = new Clan("Mojca", "Mavko", 2001, "4377"); 134: Clan c = b; 135: c.ime = "Katarina"; 136: 137: Console.WriteLine("Clan a:\n" + a.ime + " " + a.priimek + 138: " " + a.leto_vpisa + " (" + a.vpisna_st + ")\n"); 139: 140: Console.WriteLine("Clan b:\n" + b.ime + " " + b.priimek + 141: " " + b.leto_vpisa + " (" + b.vpisna_st + ")\n"); 142: 143: Console.WriteLine("Clan c:\n" + c.ime + " " + c.priimek + 144: " " + c.leto_vpisa + " (" + c.vpisna_st + ")\n"); 145: } 146: }Zgornji program deluje povsem enako kot prejnji testni program, je pa vsekakor bolj pregleden. Namen konstruktorja je, da nastavi vrednosti komponent objekta. Ker konstruktorji (pa tudi druge metode znotraj razreda) zelo pogosto dostopajo do komponent, nam C# omogoa, da namesto this.komponenta piemo kar komponenta:

RAZRED CLAN (BREZ THIS) 124: public class Clan { 125: public string ime; 126: public string priimek; 127: public int leto_vpisa; 128: public string vpisna_st; 129: 130: public Clan() { 131: ime = "Ne vem"; 132: priimek = "Ne vem"; 133: leto_vpisa = 0;Programiranje 1 VS Informatika

C# . NET

34

134: 135: 147: 136: 137: 138: 139: 140: 141: 142: }

vpisna_st = "Ne vem"; } public Clan(string i, string p, int l, string v) { ime = i; priimek = p; leto_vpisa = l; vpisna_st = v; }

Objektne metode Svoj pravi pomen dobi sestavljanje razredov takrat, ko objektu pridruimo e metode, torej znanje nekega objekta. Kot e vemo iz uporabe vgrajenih razredov, metode nad nekim objektom kliemo tako, da navedemo ime objekta, piko in ime metode. Tako e elimo izvesti metodo WriteLine nad objektom System.Console napiemo

System.Console.WriteLine("To naj se izpie");e elimo izvesti metodo Equals nad nizom besedilo, napiemo

besedilo.Equals(primerjava)in tako dalje. Denimo, da potrebujemo metodo, ki vrne inicialke nekega lana. To bomo napisali takole:

METODA V RAZREDU CLAN 148: public string Inicialke() { 149: return this.ime[0] + "." + this.priimek[1] + "."; 150: }Oglejmo si e uporabo te metode v nekem testnem programu:

TESTCLAN151: public class TestClan{ 152: public static void Main(string[] args) { 153: Clan a = new Clan("Janez", "Starina", 2000, "2304"); 154: string inicialnkeClanaA = a.Inicialke(); 155: Console.Write("Clan a:\n" + a.ime + " " + a.priimek + 156: " " + a.leto_vpisa + " (" + a.vpisna_st + ") "); 157: Console.WriteLine("ima inicialke: " + inicialnkeClanaA); 158: } 159: }Denimo, da smo kasneje ugotovili, da bi bili uporabniki razreda Clan veliko bolj zadovoljni, e bi metoda Inicialke vrnila niz brez pik, le s presledkom med zaetnico imena in priimka. Kaj storiti? Potrebno je popraviti le razred Clan, kjer spremnimo metodo

METODA V RAZREDU CLAN 160: public string Inicialke() { 161: return this.ime[0] + " " + this.priimek[0]; 162: }Ko razred ponovno prevedemo, imamo e vse pripravljeno za "pravilno" izvajanje vseh tistih programov, ki uporabljajo ta razred. Brez kakrnekoli spremembe v uporabnikem programu (in tudi brez ponovnega prevajanja tega programa), metoda sedaj deluje v skladu z v razredu narejenimi spremembami. e torej opazimo, da je potrebno v razredu narediti kaken popravek, le vsem naim uporabnikom poljemo novo razliico prevedenega razreda (ali knjinice, ki vsebuje ta razred). Brez kakrnihkoli sprememb na strani uporabnika njihovi programi delujejo "popravljeno". Programiranje 1 VS Informatika

C# . NET

35

Vemo, da z

a = b;kjer sta a in b obe spremenljivki tipa Clan, v a ne shranimo kopije objekta b, ampak sedaj a in b oznaujeta isti objekt. Zato napiimo metodo, ki naredi kopijo objekta. a = b.Kopija(); V a je nov objekt, ki pa ima iste podatke kot b.

KOPIJA

OBJEKTA

163: public Clan Kopija() { 164: Clan nov = new Clan(); 165: nov.ime = this.ime; 166: nov.priimek = this.priimek; 167: nov.leto_vpisa = this.leto_vpisa; 168: nov.vpisna_stevilka = 169: this.vpisna_stevilka; 170: }Uporabna je tudi metoda, ki izpie objekt

IZPIS

OBJEKTA

171: public void Izpis() { 172: Console.WriteLine("Clan:\n" + this.ime + " " + 173: this.priimek + " " + this.leto_vpisa + 174: " (" + this.vpisna_st + ")\n"); 175: }ali pa e

OPIS

OBJEKTA

176: public string Opis() { 177: return this.ime + " " + this.priimek + " " + 178: this.leto_vpisa + 179: " (" + this.vpisna_st + "); 180: }e sedaj navedemo celotni razred

RAZRED CLAN181: public class Clan { 182: public string ime; 183: public string priimek; 184: public int leto_vpisa; 185: public string vpisna_st; 186: 187: public Clan() { 188: ime = "Ne vem"; 189: priimek = "Ne vem"; 190: leto_vpisa = 0; 191: vpisna_st = "Ne vem"; 192: } 193: 194: public Clan(string i, string p, int l, string v) : this() { 195: ime = i; 196: priimek = p; 197: leto_vpisa = l;Programiranje 1 VS Informatika

C# . NET

36

198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: }

vpisna_st = v; } public string Inicialke() { return this.ime[0] + "." + this.priimek[0] + "."; } public Clan Kopija() { Clan nov = new Clan(); nov.ime = this.ime; nov.priimek = this.priimek; nov.leto_vpisa = this.leto_vpisa; nov.vpisna_stevilka = this.vpisna_stevilka; return nov; } public void Izpis() { Console.WriteLine("Clan:\n" + this.ime + " " + this.priimek + " " + this.leto_vpisa + " (" + this.vpisna_st + ")\n"); } public string Opis() { return this.ime + " " + this.priimek + " " + this.leto_vpisa + " (" + this.vpisna_st + "); }

In e zgled uporabe tega razreda

UPORABA RAZREDA CLAN225: public class TestKlub { 226: public static void Main(string[] args) { 227: 228: Clan a = new Clan("Janez", "Starina", 2000, "2304"); 229: Clan b = new Clan("Mojca", "Mavko", 2001, "4377"); 230: Clan c = b; 231: c.ime = "Andreja"; 232: Clan d = b.Kopija(); 233: 234: Console.WriteLine("Clan a"); a.Izpis(); 235: Console.WriteLine("Clan b:\n" + b.Opis()); 236: Console.WriteLine("Clan c:\n" + c.Opis()); 237: Console.WriteLine("Clan d"); d.Izpis(); 238: Console.ReadLine(); 239: } 240: }

Programiranje 1 VS Informatika

C# . NET

37

ZglediDatum Denimo, da v naih programih pogosto delamo z datumi. Zato bomo sestavili ustrezni razred. Najprej moramo pripraviti nart razreda. Odloiti se moramo torej, kako bi hranili podatke o datumu. Podatki, ki sestavljajo datum, so: o dan (tevilo) o mesec (izbira: tevilo ali pa niz) o Leto (tevilo) Denimo, da se odloimo, da bomo dan in leto hranili kot tevilo, mesec pa kot niz (torej kot januar, februar, ...). Sedaj se moramo odloiti, katere metode bo poleg konstruktorjev poznal na razred. Nekaj idej: o Lepo izpii o Poveaj za 1 dan o Je datum smiselen o Je leto prestopno o Nov datum za toliko in toliko dni pred/za danim datumom o Dan v tednu o ... Potem, ko smo si pripravili nart, se lotimo sestavljanja razreda

RAZRED DATUM241: public class Datum { 242: public int dan; 243: public string mesec; 244: public int leto; 245: public Datum() { 246: dan = 1; 247: mesec = "januar" 248: leto = 2000; 249: } // privzeti datum je torej 1.1.2000Dodajmo e dva konstruktorja

250: 251: 252: 253: 254: 255: 256: 257:

public Datum(int leto) : this() { this.leto = leto; // this je nujen } // datum je torej 1.1.leto public Datum(int d, string m, int l) : this(l) { // leto smo e nastavili this.mesec = m; // this ni nujen this.dan = d; } // datum je torej d.m.l

Sedaj se lahko lotimo metod. Kot prvno, nas zanima, ali je leto prestopno

258: public bool JePrestopno() { 259: int leto = this.leto; 260: if (leto % 4 != 0) return false; 261: if (leto % 400 == 0) return true; 262: if (leto % 100 == 0) return false; 263: return true; 264: }Vejih teav ni bilo. No, verjetno bolj uporabna pa bop metoda, ki bo dani datum poveala za en dan. To pomeni, da bomo objektu, nad katerim bomo metodo izvedli, poveali dan za 1. Potem pa se lahko zaplete, saj s tem lahko naredimo neobstoje datum, recimo 32. Januar. Sveda ne smemo pozabiti na prestopna leta. Lotimo se metode

Programiranje 1 VS Informatika

C# . NET

38

265: public void PovecajZaEnDan() { 266: dan = dan + 1; 267: if (dan < 29) return; 268: if (dan == 29 && mesec != "februar") return; 269: if (dan == 29 && mesec == "februar" && this.JePrestopno()) return; 270: // lahko nehamo, mesec in leto sta ok 271: string[] meseciPo30 = {"april","junij","september", "november"}; 272: if (dan == 31) { 273: if (meseciPo30.IndexOf(mesec) > 0){ 274: mesec = mesec + 1; 275: if (mesec == 13) { 276: mesec = 1; 277: leto++; 278: } 279: return; 280: } 281: // e je 32 dni, je zagotovoKo privandramo do sem, pa ugotovimo da imamo teave. Vrstica 34 je pa napana (sintaktino sicer pravilna, a pomensko povsem zgreena). Ker v spremenljivki mesec hranimo niz, bi morali namesto poveanja za 1 vzeti naslednje ime meseca. Tudi vrstica 35 je narobe .... Ko e enkrat premislimo, vidimo, da bi lo z manj truda, e bi si tudi za mesec namesto imena meseca raje zapomnili kar tevilko. e elimo datum videti z imeni mesecev pa za to lahko poskrbimo denimo ob izpisu. Zato se spodobi lotiti stestavljanja razreda datum znova. Vendar to, kot tudi preostale metode z naega spiska, prepustimo bralcu v izziv. Denimo, da smo razred Datum uspeno naredili. Sedaj pa ga e koristno uporabimo. Denimo, da elimo ugotoviti, e je letonje leto prestopno. Dovolj bo, e le naredimo objekt, v katerega shranimo katerikoli letonji datum in pokliemo pripravljeno metodo JePrestopno().

JE

LETONJE LETO PRESTOPNO

282: using MojiRazredi; 283: public class JeLetosPrestopnoLeto { 284: Datum danes = new Datum(22, 1, 2008); 285: if (danes.jePrestopno()) { 286: Console.WriteLine("Je prestopno leto"); 287: } else { 288: Console.WriteLine("Ni prestopno leto"); 289: } 290: }Fibonaccijevo zaporedje V naravi vekrat opazimo zanimive vzorce. Tako e gremo teti koliko je zrn v posamezni spirali sonninega cveta pa tudi npr v tevilu lusk ananasa, brovega stora, semen na jagodi ... dobimo zanimivo zaporedje, ki ga imenujemo Fibonnaccijevo zaporedje. Fibonaccijeva tevila definiramo z zaetnima pogojema (prvo in drugo tevilo sta enaka 1) ter z rekurzivno formulo (n-to Fibonaccijevo tevilo je vsota prejnjih dveh) . S temi podatki lahko izraunamo vsa ostala tevila. Fibonaccijevo zaporedje je torej 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ... e zaetna pogoja spremenimo (rekurzivno pravilo pa ostane isto), dobimo posploena Fibonaccijeva tevila. e si npr. za prvo tevilo izberemo 3 in za drugo -1 dobimo zaporedje tevil 3, -1, 2, 1, 3, 4, 7, 11... Sestavimo razred PosploseniFibonacci, ki bo vseboval metodo public int VrniNto(int n), ki bo izraunal n-to posploeno Fibonaccijevo tevilo. Razred naj vsebuje dva konstruktorja: publicPosploseniFibonacci() - ta naj za zaetni pogoj postavi pogoj za obiajna Fibonaccijeva tevila.

Programiranje 1 VS Informatika

C# . NET

39

public PosploseniFibonacci(int prvo, int drugo) - temu podamo vrednosti prvega in drugega posploenega Fibonaccijevega tevila. e torej ustvarimo objekta PosploseniFibonacci fibo = new PosploseniFibonacci() in PosploseniFibonacci splosni = new PosploseniFibonacci(3, -1) nam klica metod fibo.VrniNto(4) in splosni.VrniNto(4) vrneta 3 oz. 1. Hraniti bo potrebno zaetna lena

RAZRED POSPLOENIFIBONACCI291: public class PosploseniFibonacci { 292: public int prvo; 293: public int drugo; 294: 295: public PosploseniFibonacci() { 296: this.prvo = 1; 297: this.drugo = 1; 298: } 299: 300: public PosploseniFibonacci(int p, int d) { 301: this.prvo = p; 302: this.drugo = d; 303: }Metoda bo enostaven primer uporabe rekurzije

304: public int VrniNto(int n) { 305: if (n == 1) return this.prvo; 306: if (n == 2) return this.drugo; 307: return this.VrniNto(n 2) + 308: this.VrniNto(n 1); 309: }Tako, konali smo. A ni nam preve ue hitrost tega naega razreda. Bi lo hitreje? Zelo pogosto potrebujemo prvih 20 lenov Fibonnacijevega zaporedja, ostala pa bolj redko. Kaj storiti, da izboljamo odzivnost? Naj objekt hrani tabelo prvih 20 lenov, e potem uporabimo VrniNto(i) in je i Konstantnega polja ne moremo spremeniti

Dedovanje (Inheritance) izpeljani razrediKaj je to dedovanjeDedovanje (Inheritance) je kljuni koncept objektno orientiranega programiranja. Smisel in pomen dedovanja je v tem, da iz e zgrajenih razredov skuamo zgraditi bolj kompleksne, ki bodo znali narediti nekaj uporabnega. Dedovanje je torej orodje, s katerim se izognemo ponavljanju pri definiranju razlinih razredov, ki pa imajo ve ali manj znailnosti skupnih. Opredeljuje torej odnos med posameznimi razredi. Vzemimo pojem sesalec iz biologije. Kot primer za sesalce vzemimo npr. konje in kite. Tako konji kot kiti ponejo vse kar ponejo sesalci nasploh (dihajo zrak, skotijo ive mladie, ), a prav tako pa imajo nekatere svoje znailnosti (konji imajo npr. tiri noge, ki jih kiti nimajo, imajo kopita, , obratno pa imajo npr. kiti plavuti, ki pa jih konji nimajo, ..). V Microsoft C# bi lahko za ta primer modelirali dva razreda: prvega bi poimenovali Sesalec, in drugega Konj, in obenem deklarirali, da je Konj podeduje (inherits) Sesalca. Na ta nain bi med sesalci in konjem vzpostavili povezavo v tem smislu, da so vsi konji sesalci (obratno pa seveda ne velja!). Podobno lahko deklariramo razred z imenom Kit, ki je prav tako podedovan iz razreda Sesalec. Lastnosti, kot so npr, kopita ali pa plavuti pa lahko dodatno postavimo v razred Konj oz. razred Kit.

Bazini razredi in izpeljani razrediSintaksa, ki jo uporabimo za deklaracijo, s katero elimo povedati, da razred podeduje nek drug razred, je takale:class IzpeljaniRazred : BaziniRazred { . . . }

Izpeljani razred deduje od bazinega razreda. Za razliko od C++, lahko razred v C# deduje najve en razred in ni mono dedovanje dveh ali ve razredov. Seveda pa je lahko razred, ki podeduje nek bazini razred, zopet podedovan v e bolj kompleksen razred. Primer: Radi bi napisali razred, s katerim bi lahko predstavili toko v dvodimenzionalnem koordinatnem sistemu. Razred poimenujmo Tocka:class Tocka //bazini razred { public Tocka(int x, int y) { //telo konstruktorja } //telo razreda Tocka }

//konstruktor

Sedaj lahko definiramo razred za tridimenzionalno toko z imenom Tocka3D, s katerim bomo lahko delali objekte, ki bodo predstavljali toke v tridimenzionalnem koordinatnem sistemu in po potrebi dodamo e dodatne metode:class Tocka3D : Tocka //razred Tocka3D podeduje razred Tocka { //telo razreda Tocka3D tukaj zapiemo e dodatne metode tega razreda!

Programiranje 1 VS Informatika

C# . NET

140

}

Klic konstruktorja bazinega razredaVsi razredi imajo vsaj en konstruktor (e ga ne napiemo sami, nam prevajalnik zgenerira privzeti konstruktor). Izpeljani razred avtomatino vsebuje vsa polja bazinega razreda, a ta polja je potrebno ob kreiranju novega objekta inicializirati. Zaradi tega mora konstruktor v izpeljanem razredu poklicati konstruktor svojega bazinega razreda. V ta namen se uporablja rezervirana besedica base:class Tocka3D : Tocka ////razred Tocka3D podeduje razred Tocka { public Toca3D(int z) :base(x,y) //klic bazinega konstruktorja Tocka(x,y) { //telo konstruktorja Tocka3D } //telo razreda Tocka3D }

e bazinega konstruktorja v izpeljanem razredu ne kliemo eksplicitno (e vrstice :base(x,y) ne napiemo!), bo prevajalnik avtomatino zgeneriral privzeti konstruktor. Ker pa vsi razredi nimajo privzetega konstruktorja (v veliko primerih napiemo lastni konstruktor), moramo v konstruktorju znotraj izpeljanega razreda obvezno najprej klicati bazini konstruktor (rezervirana besedica base). e klic izpustimo (ali ga pozabimo napisati) bo rezultat prevajanja compile-time error:class Tocka3D : Tocka //razred Tocka3D podeduje razred Tocka { public Tocka3D(int z) //NAPAKA - POZABILI smo klicati bazini konstruktor razreda Tocka { //telo konstruktorja Tocka3D } //telo razreda Tocka3D }

Doloanje oz. prirejanje razredovPoglejmo e, kako lahko kreiramo objekte iz izpeljanih razredov. Kot primer vzemimo zgornji razred Tocka in iz njega izpeljani razred Tocka3D.class Tocka //bazini razred { //telo razreda Tocka } class Tocka3D: Tocka //razred Tocka3D podeduje razred Tocka { //telo razreda Tocka3D }

Iz razreda Tocka izpeljimo e dodatni razred Daljicaclass Daljica:Tocka //razred Daljica podeduje razred Tocka { //telo razreda Daljica }

Kreirajmo sedaj nekaj objektov:Tocka A = new Tocka(); Tocka3D B = A; //NAPAKA

- razlini tipi

Tocka3D C = new Tocka3D (); Tocka D = C; //OK!

Programiranje 1 VS Informatika

C# . NET

141

Nove metodeRazredi lahko vsebujejo ve ali manj metod in slej ko prej se lahko zgodi, da se pri dedovanju v izpeljanih razredih ime metode ponovi v izpeljanem razredu torej napiemo metodo, katere ime, tevilo in tipi parametrov se ujemajo z metodo bazinega razreda. Pri prevajanju bomo zato o tem dobili ustrezno opozorilo - warning. Metoda v izpeljanem razredu namre v tem primeru prekrije metodo bazinega razreda. e npr. napiemo razred Tocka in nato iz njega izpeljemo razred Tocka3D,class Tocka //bazni razred { private int x, y; //polji razreda Tocka public void Izpis() //metoda za izpis koordinat razreda Tocka { Console.WriteLine("Koordinate toke:\nx = " + x + "\ny = " + y); } } class Tocka3D : Tocka { private int z; //razred Tocka3D je izpeljan iz razreda Tocka //dodatno polje razreda Tocka3D

//Metoda Izpis prepie istoimensko metodo razreda Tocka public void Izpis() { Console.Write("z = " + z + "\n"); } }

nam bo prevajalnik zgeneriral opozorilo, s katerim nas obvesti, da metoda Tocka3D.Izpis prekrije metodo Tocka.Izpis:

Program se bo sicer prevedel in tudi zagnal, a opozorilo moramo vzeti resno. e namre napiemo razred, ki bo podedoval razred Tocka3D, bo uporabnik morda priakoval, da se bo pri klicu metode Izpis pognala metoda bazinega razreda, a v naem primeru se bo zagnala metoda razreda Tocka3D. Problem seveda lahko reimo tako, da metodo Izpis v izpeljanem razredu preimenujemo (npr. Izpis1), e bolja reitev pa je ta, da v izpeljanem razredu eksplicitno povemo, da gre za NOVO metodo to storimo z uporabo operatorja new.class Tocka //bazni razred { private int x, y; //polji razreda Tocka public void Izpis() //metoda za izpis koordinat razreda Tocka { Console.WriteLine("Koordinate toke:\nx = " + x + "\ny = " + y); } } class Tocka3D : Tocka { private int z; //razred Tocka3D je izpeljan iz razreda Tocka //dodatno polje razreda Tocka3D

//Z operatorjem new napovemo, da ima razred Tocka3D SVOJO LASTNO

metodo Izpis

new public void Izpis(){ Console.Write("z = " + z + "\n"); } }

Vaja:

Programiranje 1 VS Informatika

C# . NET

142

/*Napii razred krog z zasebnim poljem polmer in lastnostmi Premer, Obseg in Kvadratura. Iz razreda nato izpelji razred Krogla, dodaj razredu lastno metodo Kvadratura in novo metodo Volumen*/ class Krog //Bazini razred { private double polmer;//zasebno polje razreda Krog public double Polmer //lastnost za dostop do polja polmer { get { if (polmer < 0) return 0.00; else return polmer; } set { polmer = value;} } public double Premer //lastnost, ki vrne premer kroga { get { return Polmer * 2; } } public double Obseg //lastnost, ki vrne obseg kroga { get { return Premer * Math.PI; } } public double Kvadratura //lastnost, ki vrne ploino kroga { get { return Math.PI*Math.Pow(Polmer,2); } } } /*Kreirajmo razred Krogla ki naj podeduje razred Krog. Razred Krogla bo podedoval polje polmer, podedoval bo lastnosti Premer in Obseg, imel bo SVOJO lastnost za izraun kvadrature, poleg tega pa e novo lastnost za izraun prostornine krogle */ class Krogla : Krog { new public double Kvadratura //z operatorjem new smo oznaili, da ima razred krog SVOJO //lastno lastnost kvadratuta { get { return 4 * Math.PI*Math.Pow(Polmer,2); } } public double Volumen //nova lastnost razreda Krogla { get { return 4 * Math.PI * Math.Pow(Polmer,2) / 3; } } } //glavni program static void Main() { Krog c = new Krog();//nov objekt razreda Krog c.Polmer = 25.55; Console.WriteLine("Karakteristike kroga"); Console.WriteLine("Polmer : {0}", c.Polmer); Console.WriteLine("Premer : {0}", c.Premer); Console.WriteLine("Obseg : {0,-10:F2}", c.Obseg); Console.WriteLine("Ploina: {0,-10:F2}", c.Kvadratura); Krogla s = new Krogla();//nov objekt razreda Krogla s.Polmer = 25.55; Console.WriteLine("\nKarakteristike krogle"); Console.WriteLine("Polmer : {0}", s.Polmer); Console.WriteLine("Premer : {0}", s.Premer); Console.WriteLine("Obseg : {0,-10:F2}", s.Obseg); Console.WriteLine("Povrina : {0,-10:F2}", s.Kvadratura); Console.WriteLine("Prostornina: {0,-10:F2}\n", s.Volumen); }

Programiranje 1 VS Informatika

C# . NET

143

Virtualne metodePogosto elimo metodo, ki smo je napisali v bazinem razredu, v vijih (izpeljanih) razredih skriti in napisati novo metodo, ki pa bo imela enako ime in enake parametre. Eden izmed nainov je uporaba operatorja new za tako metodo, drug nain pa je z uporabo rezervirane besede virtual. Metodo, za katero elimo e v bazinem razredu oznaiti, da jo bomo lahko v nadrejenih razredih nadomestili z novo metodo (jo prekriti), oznaimo kot virtualno (virtual), npr.://virtualna metoda v bazinem razredu v izpeljanih razredih bo lahko prekrita(override) public virtual void Koordinate() {...}

V nadrejenem razredu moramo v takem primeru pri metodi z enakim imenom uporabiti rezervirano besedico override, s katero povemo, da bo ta metoda prekrila/prepisala bazino metodo z enakim imenom in enakimi parametri.//izpeljani razred besedica override pomeni, da smo s to metodo prekrili bazino metodo public override void Koordinate() { ...}

Loiti pa moramo razliko med tem, ali neka metoda prepie bazino metodo (override) ali pa jo skrije. Prepisovanje metode (overriding) je mehanizem, kako izvesti drugo, novo implementacijo iste metode virtualne in override metode so si v tem primeru sorodne, saj se priakuje, da bodo opravljale enako nalogo, a nad razlinimi objekti (izpeljanimi iz bazinih razredov, ali pa iz podedovanih razredov). Skrivanje metode (hiding) pa pomeni, da elimo neko metodo nadomestiti z drugo metode v tem primeru niso povezane in lahko opravljajo povsem razline naloge.

Primer: Naslednji primer prikazuje zapis virtualne metode Koordinate() v bazinem razredu in override metode Koordinate() v izpeljanem razredu.class Tocka //bazini razred { private int x, y; //polji razreda Tocka //metoda Koordinate je virtualna, kar pomeni, da jo lahko prepiemo (override) public virtual void Koordinate() //metoda za izpis koordinat razreda Tocka { Console.WriteLine( "Koordinate toke:\nx = "+x + "\ny = " + y); } } class Tocka3D : Tocka { private int z; //razred Tocka3D je izpeljan iz razreda Tocka //dodatno polje razreda Tocka3D

//Metoda Koordinate je oznaena kot override - prepie istoimensko metodo razreda Tocka public override void Koordinate() { base.Koordinate(); //klic bazine metode Koordinate razreda Tocka Console.Write("z = "+z+"\n"); } }

Prekrivne (Override) metodeKadar je bazinem razredu neka metoda oznaena kot virtualna (virtual), jo torej lahko v nadrejenih razredih prekrijemo/povozimo (override). Pri deklaraciji takih metod (pravimo jim polimorfne metode) z uporabo rezerviranih besed virtual in override, pa se moramo drati nekaterih pomembnih pravil: Metoda tipa virtual oz. override NE more biti zasebna (ne mre biti private); Obe metodi, tako virtualna kot override morata biti identini: imeti morata enako ime, enako tevilo in tip parametrov in enak tip vrednosti, ki jo vraata;

Programiranje 1 VS Informatika

C# . NET

144

Obe metodi morata imeti enak dostop. e je npr. virtualna metoda oznaena kot javna (public), mora biti javna tudi metoda override; Prepiemo (prekrijemo/povozimo) lahko le virtualno metodo. e metoda ni oznaena kot virtualna in bomo v nadrejenem razredu skuali narediti override, bomo dobili obvestilo o napaki; e v nadrejenem razredu ne bomo uporabili besedice override, bazina metoda ne bo prekrita. To pa hkrati pomeni, da se bo tudi v izpeljanem razredu izvajala metoda bazineg