![]() |
|
||||||
|
|
| 29.07.10 / 21:54 |
|
Martin Rebane
Loo lugemise eelduseks on kasutajafunktsioonide tundmine.Esiteks anname Sulle motiivi: pea kõik suured ja tõsiseltvõetavad programmid on kirjutatud objektorienteeritult. Niiet igaüks, kes tahab programmeerijana leiba teenida, peab paratamatult oskama objektorienteeritud programmeerimise töövõtteid. Millega tegu? Põhimõtteliselt konkreetse koodi tasemel ei erine objektorienteeritud programmeerimine(OOP) "tavalisest" programmeerimisest. St echo on ikka echo ja if on ikka if. Erinevus ja OOP vajalikkus seisneb peamiselt võimaluses programmi makrotasandil projekteerida ja arendada. Ja justnimelt programmi, mitte enam tavalist PHP skriptijuppi. Loe edasi, tegelt see ei ole nii õudne ja keeruline :) OOP kasutamine annab võimaluse hakata programmi kirjutamisel(ja eriti enne päris programmeerimise algust) planeerida programmi funktsionaalsust(ehk mida see teeb) ning modulaarsust(ehk jaotada programm osadeks: üks osa arvutab, teine joonistab, kolmas väljastab tulemuse). Selle eelisteks on see, et üks programmiosa ei ole teisest sõltuv(kuigi võib teisi osi kasutada ja nendega suhelda). OOP on paljuski dünaamilisuse sünonüüm: need programmid ei ole klassikaliselt kinnikirjutatud, võimaldavad tänu koodi väga lihtsale taaskasutavusele ja ligipääsetavusele luua väga dünaamilisi süsteeme. Nt võib ühe ja sama PHP koodiga programm kuvada(sama koodi kasutades) tavalise artikli, kasutaja profiili, hallata kuulutusi, panna lehele külalisteraamatu. Muidugi saab seda kõike teha ka "tavalise" programmeerimisega, aga mingil hetkel avastab tegija seejuures ikkagi, et OOP oleks palju lihtsam tee. Niipalju siis OOP võludest, aga jutt siirdub natuke juba programmiarhitektuuriks, seega tagasi OOP olemuse juurde. Klass, meetod ja objekt - Sinu Suured Sõbrad Meetod on sisuliselt sinu enda kirjutatud funktsioon, mis asub klassi sees. Ning klass lihtsustatult öeldes ongi ise meetodite(funktsioonide) kogum, (mis objekti luues sellele omistatakse). Näiteks: PHP kood:
Ülal on klass nimega "text", milles on saadaval meetodid "text", "print_text" ja "add", kusjuures "text" on klassi "text" konstruktorfunktsioon. St kui klassis on meetod, mis on sama nimega kui klass ise, siis klassi väljakutsumisel pannakse see funktsioon automaatselt käima. Konstruktori olemasolu ei ole vajalik. "Käima panna" saab klassi nii väljastpoolt klassi kui ka nt teise klassi seest. Selle pisikese reaga panime me klassi käima e korrektselt väljendades tekitasime uue objekti nimega $obj. Ning selle tekitamisega kutsusime automaatselt välja ka konstruktormeetodiks oleva "text" -i. Kui nüüd seda kood jätkata ja kirjutada: PHP kood:
Siis kutsusime kõigepealt välja objekti $obj meetodi add(), mis lisas konstruktorfunktsiooni poolt paika pandud muutujale $this->text meie poolt antud parameetri("See artikkel tutvustab OOP'd"). Seejärel kutsusime välja meetodi print_text, mis echo's selle muutuja sisu ning väljastas:
Siit ka siis järeldus, kuidas OOP töötab: -kui tavalistes funktsioonides saad kasutada global parameetrit, et kasutada funktsioonivälist muutujat, siis OOPs on sul klassi sees sama muutuja kasutamiseks vaja tarvitada nimekuju $this->muutujanimi, kus $this-> tähendab siis seda, et tegu on just selle objekti muutujaga. Väljaspool seda objekti antud muutujat $this-> abil kasutada ei saa. -klassi, mille "tütreke" objekt $obj on, meetodeid saab väljaspool klassi välja kutsuda, kui nende ette kirjutada objekti nimi: $obj-> Nt siis: Kui soovid klassi sees kasutada sama klassi funktsiooni, siis saab ka selle saavutada $this-> abil: PHP kood:
Kui lisada "text" klassi selline funktsioon, siis selle väljakutsumisel võtab ta etteantud teksti, muudab selle värviliseks ning annab värvilise teksti edasi meetodile add()(mis siis omakorda sellega edasi toimetab). Kuid miks ikkagi kutsutakse $obj'i objektiks ja klassis asuvaid funktsioone meetoditeks mitte näiteks muutujaks ning funktsioonideks? Tavalisel muutujal ei ole meetodeid ning tavalisi funktsioone ei saa omistada objektidele. Objektorienteerituse paremaks mõistmiseks vaatame asja sellest küljest, et pea iga inimene oskab rääkida, süüa, kõndida, magada(kõik need on OO mõistes meetodid). Aga iga inimene teeb seda omamoodi ja erinevalt: ta on isiksus, mitte lihtsalt inimene. Niisamuti on ka objekt: sama klassi baasil võib luua mitu sarnaste meetoditega objekti, kuid nende meetodite omadused võivad olla erinevad. Nii nagu iga inimene on eriline, saab seda olla ka iga objekt. PHP kood:
Niimoodi tekitasime me ühe klassi baasil kaks objekti, millel on samasugused meetodid(text, add, print_text ning color_add), kuid nad ei ole identsed, üks tekst on must ning teine punane. Siin tuleb esile ka OOP erinevus tavalistest globaalseid muutujaid kasutavatest funktsioonidest: ühe globaalse muutujaga ei saaks meil korraga olla kahte erinevat globaalset muutujat(kõlab küll tobedalt, aga tõsi ta on ju :)). Aga kui asja võrrelda tavaliste funktsioonidega, siis võib paralleelina tuua just kahe globaalse muutuja kasutamise. Tavalise funktsiooni ja globaalse muutuja korral kirjutataks punane tekst mustale otsa, objektide korral(siin näites $must ja $punane) aga hoitaks mõlema omadusi lahus. Küsime veelkord: aga milleks see vajalik on? Selgitame: Orkestris mängivad viiulit ja kontrabassi erinevad inimesed, kasutades samu noote. Sest nootidest saab koopiaid teha. Kui see võimalik ei oleks, peaks kõigepealt mängima viiuldaja ning seejärel kontrabassimängija. Ehk: OOP's saab paralleelselt samade meetodite(pillimängija) abil kasutada erinevaid objekte(viiuldaja, kontrabassimängija) erinevateks eesmärkideks(viiulimäng, kontrabassimäng). Ühel juhul on klassi sees $this->pill väärtuseks 'viiul', teisel juhul 'kontrabass' ning kontrabassimängija ei pea ootama, kuni viiuldaja lõpetab, vaid võib samal ajal mängida. Väike pseudokood, mille toimimist pole mõtet kontrollida, aga uurida tasub küll. PHP kood:
Nüüd vaatame senikirjutatud PHP koodi koos kommentaaridega üle, et asi ikka selgeks saaks. Soovitan see kood oma veebiserverisse panna ja ise järgi proovida, mismoodi asi töötab! PHP kood:
See näide oligi illustreerimaks objektide olemust ja vajalikkust, millest algajal on tavaliselt kõige keerulisem aru saada. Klasside pärimine e tuletamine e deriveerumine Kui ma kirjutaksin samasse faili nüüd veel ühe klassi, siis ma saaksin ka seda eraldi kasutada: Aga kui nüüd klassi defineerimisel muuta esimest rida: PHP kood:
...saame klassi, milles on olemas ka esimeses klassis defineeritud meetodid ja muutujad. Selles veendumiseks asenda koodis $must ja $punane väärtustamine: PHP kood:
Hoolimata sellest, et uues klassis ei ole veel ühtegi meetodit, on tulemus sama, kui siis, kui lõime uue objekti text klassi põhjal. PHP kood:
Lisades uude klassi funktsiooni border, saame seda kasutada nii klassiväliselt objektiga manipuleerides: Kui ka nt text klassi seest: Aga milleks kaks klassi, kui ma võiksin selle funktsiooni ka kohe esimesse klassi kirjutada? Tõepoolest, kuid siis võiks küsida seda, kas sa oled kindel, et sul igal veebilehel, kus sa oma programmi kasutad, läheb vaja just neid ühtesid ja samu funktsioone? Arvatavasti nii ja naa: osa funktsioone kasutad sa igal lehel: andmebaasifunktsioonid, põhilised teksti- või failitöötlusfunktsioonid. Aga enamus funktsioone ei ole igal pool kasutuses: nt foorumi funktsioonidel pole galerii kuvamisel suurt midagi kaasa rääkida. Siin tulebki ette olukord, mida on võimalik lahendada nii, et põhifunktsioonid on ühes klassis ning olenevalt veebilehe iseloomust võetakse laiendavaks klassiks iga kord ainult vajaminevate meetoditega klass. Objektorienteeritud programmeerimisega alustamiseks on sobiv võtta mõni oma varasem tavalisi funktsioone kasutav programm ning püüda see ümber kirjutada OO printsiipe kasutades. Ja kui OO juba käe sees on, siis mõelda, millise objektorienteeritud programmiga, mille sa kohe kirjutad, maailma vallutama minna ;) PS! OO on lihtne, aga ainult alustamine on raske. Kui Sa esimese korraga pihta ei saanud, siis puhka natuke, süvene ja loe uuesti. Ning küsi abi PHP.ee foorumist :) Artikli kommentaarid |
|