uvod v enkapsulacijo to poglavje je bistveno pri spoznavanju objektno usmerjenega programiranja enkapsuliranemu objektu pogosto pravimo abstraktni podatkovni tip smisel enkapsulacije je skrijemo oziroma zavarujemo del programske kode tako da je ne moremo pomotoma pokvariti pravimo da del podatkov skrijemo primer programa open cpp program open cpp je v bistvu neumen saj ne pocne nic pametnega vendar omogoca razumevanje ideje o skrivanju podatkov v vrsticah do je definiran tip preproste strukture ki vsebuje eno samo spremenljivko tipa int v vrstici imamo definirane tri take strukture v samem programu so spremenljivke teh struktur nastavljene in kasneje izpisane njihovo obliko in vsebino prikazuje spodnja slika skrivanje podatkov primer programa clas cpp program clas cpp kaze kako lahko podatke skrijemo podoben je prejsnjemu vendar opazimo nekaj razlik tako smo v vrstici namesto besedice struct uporabili class s to besedico deklariramo razred class v razliko od struktur pri katerih so komponente naceloma javne public so komponente razredov naceloma privatne in tako skrite zunanjemu svetu v nasem primeru smo v razredu one datum spremenljivki data store dodali se dve funkciji set in get value ti dve funkciji sta prav tako kot sama spremenljivka komponenti deklariranega razreda kaj je privatna sekcija vsi podatki ali bolje komponente ali cleni ki zacenjajo seznam razreda so privzeto privatni zato niso dostopni izven tega razreda spremenljivke data store ki je del objekta pojem objekta bomo kmalu spoznali z imenom dog v programu main ne bi mogli uporabiti med nami in to spremenljivko je nekaksen zid ki ga ponazoruje spodnja slika v tem zidu pa sta luknji ki nam omogocata dostop do funkcij set in get value ti luknji smo dobili tako da smo obe funkciji deklarirali v javni sekciji public razreda kaj je sekcija public vrstica uvaja kljucno besedo public ta pove da bo vse kar sledi tej besedi javno oziroma dostopno programu ki uporablja objekte tega razreda tako smo lahko definirali dve funkciji ki nam edini omogocata posredni dostop do skrite spremenljivke takim funkcijam ki so clani nekega razreda prvimo clanske funkcije member functions potem ko smo deklarirali take funkcije moramo se povedati kaj te funkcije sploh delajo v nasem primeru storimo to v vrsticah tu je vsaka funkcija definirana na obicajen nacin novo je le to da smo pred ime vsake funkcije dodali ime razreda vmesno locilo pa je dvojno podpicje tema dvema definicijama funkcij pravimo implementacija funkcij ime razreda potrebujemo zato ker lahko uporabimo enako ime funkcije tudi v drugih razredih in mora prevajalnik vedeti kateremu razredu pripada neka implementacija funkcije bistveno je da so privatni podatki nekega razreda dostopni funkcijam tega razreda ne pa funkcijam drugih razredov v splosnem lahko definiramo tako v sekciji privat kot v sekciji public tako spremenljivke kot funkcije obicajno pa je da so spremenljivke vecinoma skrite v privatni sekciji funkcije pa so vecinoma definirane v javni sekciji v c imamo stiri dosege veljavnosti scope spremenljivk global local file in class globalne spremenljivke so dostopne povsod tako v datoteki kjer so definirane kot v drugih datotekah spremenljivke dosega file so tiste ki so definirane izven vseh funkcij dostopne so kjerkoli znotraj datoteke v kateri so definirane spremenljivka v dosegu razreda class je dostopna samo znotraj razreda vkljucno z implementacijsko kodo vendar nikjer drugje vec v nasem primeru ima tak doseg spremenljivka data store se nekaj besed o izrazoslovju razred class je skupek podatkov in metod funkcij podoben je strukturnemu tipu poznanemu pri ansi c objekt object je instanca razreda kar je podobno kot so spremenljivke instance dolocenega podatkovnega tipa object je to kar uporabljamo v nasem programi in vsebuje vsrednosti ki jih lahko spreminjamo metoda method je funkcija ki jo vsebuje razred sporocilo message je ekvivalentno funkcijskemu klicu pri objektno usmerjenem programiranju posiljamo sporocila namesto klicev funkcij no v resnici stvar ni cisto ekvivalentna sedaj lahko v luci teh spoznanj nadaljujemo s proucevanjem programa clas cpp imamo torej razred z eno spremenljivko in dvema metodama metodi delujeta na spremenljivki ki je vsebovana v razredu in to takrat ko dobita ustrezni zahtevek oziroma sporocilo pozor na vrstici in v njih sta podana podana prototipa dveh metod kar navedemo kar v definiciji razreda metoda z imenom set terja en parameter tipa int in ne vraca nic zato je njen return tip void metoda get value pa je brez parametrov in vraca vrednost tipa int posredovanje sporocil oglejmo si program ki uporablja ta razred v vrstici so definirani trije objekti dog dog in dog iz razreda one datum vsak objekt ima podatek ki pa ga lahko nastavljamo le posredno z uporabo metode set ali beremo njegovo vrednost z uporabo metode get value direktno do takega podatka ne moremo priti ker je skrit pravimo da posiljamo objektu sporocila messages tako v vrstici posiljamo objektu dog sporocilo da naj nastavi svojo interno vrednost na posredovanje sporocil je na videz podobno funkcijskim klicem podobno nastavimo s posredovanjem ustreznih sporocil tudi vrednosti objektov dog in dog vrstici in have sta zakomentirani ker vsebujeta nelegalno kodo spremenljivka data store je namrec oznacena kot private in je zato koda izven objekta ne doseze povejmo se da podatka v objektu dog metode v objektih dog in dog ne dosezejo ker so pac to drugi objekti program vsebuje tudi eno navadno spremenljivko piggy ki je v programu deklarirana in uporabljena v ilustracijo da lahko mesano uporabljamo objekte in navadne spremenljivke problematicen program primer programa openpole cpp oglejmo si primer programa v katerem se srecamo s problemi ki jih enkapsulacija lahko resi imamo deklariran tip strukture rectangle v programu sta definirani dve strukturi tega tipa box in square v programu mnozimo visino in sirino height in width obicajno pomeni tak produkt povrsino nekega lika v primeru mnozenja sirine enega objekta z visino drugega pa dobimo nesmisel je pa tak zapis s stalisca jezikov c in c povsem legalen uporaba objektno usmerjenega programiranja lahko take nesmisle prepreci objekti scitijo podatke primer programa claspole cpp v tem programu je rectangle spremenjen v razred class z enakima spremenljivkama kot prej le da sta sedaj private dodani sta se dve metodi ki omogocata uporabo teh privatnih podatkov eno metodo uporabljamo za inicializacijo vrednosti teh podatkov druga metoda pa racuna njun produkt in s tem povrsino ceprav sta oba objekta square in box iz istega razreda so njuni podatki skriti in do zmesnjav ne more priti ste to tehniko ze uporabljali dober primer uporabe tehnike enkapsulacije je ze znano delo z datotekami podatke iz datotek lahko dobimo le s pomocjo vnaprej dolocenih funkcij ki jih daje na voljo prevajalnik sami direktno do podatkov na fizicnih naslovih diska ne moremo priti pridemo lahko do podatkov ki jih res potrebujemo do drugih sistemskih podatkov pa ne kar preprecuje rusenje datotecnega sistema na disku podobnih primerov je se vec vidimo da temelji objektno usmerjenega programiranja pravzaprav obstajajo ze dolgo konstruktorji in destruktorji primer programa conspole cpp ta program uvaja pojem konstruktorjev in destruktorjev je pa sicer podoben prejsnjemu konstruktor ima vedno enako ime kot sam razred deklariran je v vrstici definiran pa v vrsticah do konstruktor klice sistem c avtomaticno vsakokrat ko je deklariran nek objekt iz tega razreda to preprecuje uporabo neinicializiranih spremenljivk ko v vrstici definiramo objekt z imenom box je konstruktor klican avtomaticno konstruktor nastavi v objektu box spremenljivki height in width na to lahko kontroliramo s testnim izpisom v vrsticah in podobno se zgodi ko v vrsticfi definiramo objekt square tudi tu avtomatsko poklicani konstruktor nastavi vrednosti spremenljivk height in width objekta square na vrednost konstruktor ima v svoji definiciji enako ime kot njemu ustrezen razred v nasem primeru se oba imenujeta rectangle konstruktorju ne navajamo tipa return ker ze ima vnaprej dolocen tip to je tip kazalca na tvorjeni objekt v nasem primeru konstruktor sicer spremenljivkam obeh objektov dodeli zacetne vrednosti vendar jih v vrsticah in spremenimo ker opravi inicializacijo ze konstruktor je ime metode initialize morda neprimerno in bi ga bilo bolje spremeniti destruktor je konstruktorju precej podoben klican pa je avtomaticno ko gremo iz obmocja obsega scope danega objekta spomnimo se da imajo avtomatske spremenljivke omejeno zivljensko dobo in obstojajo le v bloku v katerem so bile deklarirane podobno je z objektom ko naj bi bil dealociran je avtomatsko klican ustrezen destruktor ce seveda obstaja tudi destruktor nima tipa return v nasem primeru je destruktor klican v vrstici in definiran v vrsticah od do v nasem primeru destruktor le priredi spremenljivkam predno so te dealocirane vrednost torej se v bistvu ne zgodi nic ce pa bi v objektu imeli na primer dinamicno alocirane bloke pomnilnika bi jih morali v destruktorju sprostiti preden zgubimo kazalce nanje tako bi tak pomnilnik lahko sprostili in pozneje v programu ponovno uporabljali zanimivo je da v primeru objekta ki ga kot globalne spremenljivke deklariramo pred funkcijo main ustrezen konstruktor izveden pred programom main in destruktor takega objekta se bo izvedel po zakljucku programa oziroma funkcije main pakiranje objektov primer programa boxes cpp ta primer prikazuje kako pakiramo objekt s ciljem njegove splosne uporabnosti tak nacin zadosca v primeru res majhnih programov za vecje programe ki jih obicajno delimo v vec datotek pa bomo kasneje spoznali bolj primerno metodo pakiranja v nasem primeru je razred deklariran v vrsticah do implementacijo razreda pa podajajo vrstice do razred je uporabljen v vrsticah do implementacija inline metoda v vrstici vsebuje implementacijo metode kar v delu njene deklaracije saj je le ta preprosta pri tem spoznamo se nekaj pogosto uporabljenega pri programiranju v jeziku c ce je implementacija vkljucena v deklaracijo bo prevedena inline torej povsod kjer bomo funkcijo klicali tak program bo hitrejsi saj ne pride do sicersnjega funkcijskega klica kodiranje inline je v tem smislu analogno uporabi makrojev v jeziku c oglejmo si naslednje tri primere ki ponavljajo nas program v malo drugacni obliki zaglavna datoteka razreda primer box h v datoteki box h zasledimo definicijo razreda pri tem niso podane podrobnosti kako naj bi bile implementirane posamezne metode razen seveda za metodo inline z imenom get area razred je torej popolno definiran vendar brez implementacijskih podrobnosti v bistvu smo uporabili vrstice do prejsnjega programa podanega v datoteki boxes cpp novi datoteki pravimo zaglavna datoteka header file in je same po sebi ne moremo niti prevajati kaj sele izvajati implementacijska datoteka razreda primer box cpp oglejmo si datoteko box cpp v njej so implementirane metode deklarirane v zaglavni datoteki razreda zato je zaglavna datoteka ki vsebuje prototipe teh metod in definicije spremenljivk vanjo vkljucena v vrstici kodo v vrsticah do datoteke boxes cpp uporabimo v datoteki box c za samo implementacijo metod to datoteko lahko prevedemo ne dobimo pa izvrsljivega programa saj ne vsebuje vstopne tocke main kot to zahtevajo programi pisani v c ali c pri prevodu te datoteke dobimo objektno kodo ki bo shranjena kot takoimenovana objektna datoteka v istem direktoriju in bo na voljo drugim programom pozor pojem objektne kode in objektne datoteke nima nobene zveze s pojmom objektno usmerjenega programiranja oziroma z objekti locitev definicije in implementacije je momemben korak v programskem inzenirstvu pisec novega programa potrebuje za uporabo nekega razreda le ustrezno definicijsko datoteko ne zanima ga kaksna je konkretna implementacija uporabljenih implementiranih metod ce bi imel na voljo tudi implementacijsko datoteko njeno izvorno kodo bi jo lahko proucil nasel kaksen programerski trik in morda napisal svoj program bolj ucinkovito dolgorocno pa bi to lahko povzrocilo nekompatibilnosti ko bi avtor implementacijske datoteke v le tej kaj spreminjal smisel objektno usmerjenega programiranja je tudi v skrivanju implementacije ki naj ne vpliva na nic izven njenih dobro definiranih meja oziroma takoimenovanega vmesnika interface uporaba objekta box primer programa boxes cpp oglejmo si datoteko boxes cpp in videli bomo da je v njej uporabljen pravkar definiran razred v bistvu so zadnje tri datoteke skupaj enakovredne programu boxes cpp ki smo ga najprej proucili datoteko box h smo v zadnji programski datoteki vkljucili v vrstici ker potrebujemo definicijo razreda box ce naj deklariramo take objekte in uporabimo njihove metode program se bo po prevodu obnasal tako kot njegov predhodnik vendar je med boxes cpp in boxes cpp vseeno velika razlika predvsem zamenjajmo izrazoslovje ne govorimo vec o klicanju funkcij temvec o posredovanju osporocil med obema operacijama je bistvena razlika ker so podatki nekega objekta zelo tesno vezani na ta objekt lahko do teh podatkov pridemo le preko metod in posiljamo objektu sporocila kaksne operacije naj naredi na teh podatkih pri klicu funkcij pa ji posredujemo podatke kot parametre saj funkcija ne vsebuje lastnih podatkov posteno povedano je ta razlika zelo majhna preizkusimo sedaj program najprej moramo datotekoko prevesti prevedeno datoteko moramo povezati z datoteko box obj tako dobimo izvrsljivo programsko datoteko ki jo preizkusimo ta primer nas torej hkrati uvaja v tehniko programiranja z uporabo vecjega stevila manjsih datotek primer tudi ponazarja metodo skrivanja podatkov kar bistveno vpliva na razvoj kompleksne programske opreme abstraktni tipi podatkov v zacetku poglavja smo ze omenili abstraktne tipe podatkov abstraktni tip podatkov je skupina podatkov pri kateri lahko vsak pomni vrsto verednosti in skupina metod oziroma funkcij ki lahko delujejo na teh podatkih podatki so zasciteni pred zunanjimi vplivi so torej zasciteni protected oziroma enkapsulirani interakcija med podatki v taki skupini je lahko zelo velika interakcija z zunanjim svetom pa zelo skromna objekt je skromno povezan z zunanjim svetom tudi s svojimi metodami vzdrzevanje takega objekta je torej relativno enostavno prijateljske funkcije funkcijo izven nekega razreda lahko definiramo kot razredu prijateljsko funkcijo friend function ki lahko dostopa do privatnih clanov nekega razreda to v bistvu odpre majhno luknjo v zascitni scit razreda zato moramo biti precej previdni so primeri ko postane tako program bolj razumljiv in ko zelimo vsaj skromen in nadzorovan dostop do podatkov prijateljske funkcije bomo med tecajem spoznali na vec primerih tu jih imenjamo le zaradi popolnosti poglavja prijateljsko drugim razredom lahko deklariramo eno loceno funkcijo ali clane drugih razredov celo cel razred lahko dobi status prijatelja konstruktorji in destruktorji pa ne morejo biti prijateljske funkcije konstrukt struct v c konstrukt struct je v c se vedno na voljo in deluje enako kot pri ansi c vendar z majhnim dodatkom v strukture lahko dodajamo tudi metode ki pa delujejo na podatkih enako kot pri razredih v razliko od razreda so v strukturi tako metode kot podatki privzeto javni public lahko pa jih opredelimo kot privatne z definicijo privatne sekcije v strukturi strukture uporabljajmo le za konstrukte ki so resnicne strukture tudi pri uporabi najbolj preprostih objektov raje uporabljajte razrede za njihovo definicijo zelo prakticen razred primeri enkapsulacije v tem poglavju so bili zelo enostavni za studij bolj kompleksnih primerov uvedimo razred date ta razred naj omogoca branje trenutnega datuma in njegov izpis v obliki niza ascii v enem od stirih vnaprej dolocenih formatov uporabimo ga lahko tudi za pomnenje poljubnega datuma in njegovo formatiranje za prikaz primer date h oglejmo si dobro komentirano datoteko date h ki je zaglavna datoteka razreda date v vrstici na novo opazimo rezervirano besedo protected njen pomen bomo spoznali v naslednjih poglavjih zaenkrat pa si zamislimo da ima isti pomen kot beseda private kodo v vrsticah in ter bomo spoznali na kratko zaenkrat jih kar ignorirajmo tudi besedo static uporabljeno v vrsticah in bomo spoznali kasneje ti konstrukti so uvedeni za kasnejse spoznavanje dedovanja pred nadaljevanjem tecaja dobro proucite to zaglavno datoteko primer programa date cpp datoteka date cpp uporablja razred date in ne predstavlja nic posebnega predstavlja preprosto implementacijo pomnenja in uporabnega formatiranja datuma proucite to implementacijsko datoteko pred prehodom na primer uporabe razreda date v glavnem programu implementacija konstruktorja v vrsticah do uporablja sistemske klice dos za ugotovitev trenutnegga datuma to kodo lahko tudi spremenite glede na operacijski sistem ki vam je na voljo namen te kode je le prikaz enkapsulacije in konstruktorjev ne pa resnicno branje realnega casa primer programa usedate cpp ta preprost program uporablja razred date za izpis trenutnega datuma v dveh razlicnih formatih kazalo