Objektitüübi laiendamine, prototüüp
Küllalt palju saab oma koodi korrastada, kui suhteliselt iseseisvalt toimivad
üksused objektitüüpideks ja nende juurde kuuluvateks objektideks kokku
koondada. Nii nagu tavalise järjest kirjutatud koodi kokku grupeerimisel
funktsioonidesse on võimalik saada mõistlik ülevaade vähemasti kümme korda
suuremast lahendusest, nii funktsioonide ja andmete koondamisel
objektitüüpidesse ja objektidesse annab see omakorda vähemalt sama suure võidu
programmide keerukusega hakkama saamisel. Kuni loodud uusi tüüpe on vaid mõni
ning nendest loodud objektid igaüks suhteliselt erisuguste omaduste ja
kasutuskohtadega, siis võivad tüübid ise rahumeeli üksteisest erinevad ja
sõltumatud olla. Kui aga hakkab tekkima kohti, kus objektid peaksid käituma
mõne omaduse suhtes sarnaselt, mõne omas mitte, siis võib koodi ülesehitust
otstarbekamaks muuta aidata objektitüübi laiendamine.
Käskluse lisamine
Järgnevas näites luuakse kõigepealt vektori tüüp. Isendimuutujateks x ja y ning
meetodiks pikkus. Hiljem lisatakse Vektorile prototüübi kaudu käsklus
tekstina(), mis siis selle vektori andmed viisakal kujul tekstina tagastab.
Vastuskihil näeb funktsiooni töö tulemust.
Laiendamine
Tekstina: (3, 4) kogukiirus 5
Massiivi viimane element
Tavapärasem on käskluse lisamine juba võõrastele tüüpidele, mida ise muuta ei
saa. Näitena lisatakse viimase elemendi küsimise käsklus Javaskripti
süsteemsele klassile Array. Kui muidu on võimalik massiivist eesnimed küsida
elementide arvu käsuga eesnimed.length ning viimast eesnime kujul
eesnimed[eesnimed.length-1] (sest elementide lugemine algab nullist), siis
funktsioonis objekti enese poole pöördumiseks on sõna this. Ehk siis viimase
elemendi väärtuse annab this[this.length-1].
Laiendamine
Väljund:
Mati
Ülesandeid
Lisa Vektorile prototüübi kaudu käsklus korruta(arv). Selle tulemusena
korrutatakse vektori mõlemad koordinaadid (this.x ja this.y) vastava arvuga.
Midagi ei tagastata return-käsuga. Katseta, andes vektorile algväärtused,
paludes neid kahega korrutada ning siis küsides tekstina, et mis väärtused
vektori sees nüüd on.
Lisa käsklus korrutaUueks(arv). Korrutusarvutus käib samuti kummagi koordinaadi
kohta. Nüüd aga ei muudeta väljakutsuva vektori andmeid, vaid luuakse käsu töö
käigus uus vektor oma koordinaatidega - return new Vektor(this.x*arv,
this.y*arv); Katseta.
Uuri Javaskripti standardtüüpi String. Lisa sellele prototüübi abil teatamaks,
mitmest sõnast koosneb selles stringis olev lause. Vihje: käsklus split() jagab
lause sõnade massiiviks ning siis saab massiivilt pikkust küsida.
Asukoha põhjal ring
Järgnevas näites pannakse Ringi prototüübiks Asukoha eksemplar. Ehk siis siin
näites tehakse Asukohast muutuja a, mille sees koordinaadid 3 ja 5. Ning käsuga
var a=new Asukoht(3, 5);
Ring.prototype=a;
määratakse, et kõik loodavad ringid saavad oma aluseks Asukoha eksemplari,
millest siis ringi loomisel koopia tehakse. Tulemusena saavad kõik ringid
kasutada konkreetse asukoha koordinaate ning samuti töötab käsklus tekstina(),
mis koordinaadid viisakasti sulgude vahel välja kuvab.
Laiendamine
Ringi asukoht: (3, 5), pindala 314
Ülesandeid
Pane näide tööle.
Lisa Asukohale käsklus paremale(), mis suurendab x-i väärtust ühe võrra.
Veendu, et Ringi on võimalik ka selle käskluse abil paremale nihutada, trüki
ringi asukoht enne ja pärast nihutamist.
Ülemklassi väljakutse
Eelmises näites oli ringi aluseks alati asukoht koordinaatidega 3 ja 5. Sinna
saab küll käsud panna x-i ja y-i asukoha muutmiseks, aga see mõnevõrra tüütu.
Hea, kui saab kohe määrata ringi sinna kus ta mõeldud on. Üheks mooduseks on
ringi loomise käsu seest välja kutsuda tema aluseks oleva asukoha loomise käsk.
Ehk siis luuakse kõigepealt algandmetega asukoht ja määratakse see Ringi
protüübiks. Edasi Ringi loomisel antakse x ja y edasi Asukoha konstruktorile,
mis hoolitseb uute koordinaatide salvestamise eest.
var a=new Asukoht(0, 0);
Ring.prototype=a;
function Ring(x, y, r){
Asukoht.call(this, x, y);
Näide tervikuna:
Laiendamine
Ringi asukoht: (2, 4), pindala 153.86
Ülesandeid
Pane näide tööle
Lisage ringile käsklus kasPuutub(teineRing), mis väljastab, et kas üks ring
puutub teisega kokku. Katseta toimimist.
Koosta massiiv viie ringiga. Väljasta, millised ringid puutuvad esimese ringiga
kokku.
Käskluse asendamine
Objektidega majandamine võimaldab uue objekti aluseks võtta ka objekti, mille
mõned omadused sobivad, teised aga mitte. Siin näites luuakse kõigepealt
AlusRuut, kel olemas asukoha koordinaadid ning kiirusesamm mõlema koordinaadi
suunas. Liikumisfunktsiooni käivitusega liigutakse ühe sammu jagu edasi.
Joonistuskäsu tulemusena kuvatakse etteantud graafilise konteksti sihtkohale
ruut, mille asukohaks alusruudu koordinaadid ning külje pikkuseks viis ühikut.
Kui nüüd soovida ringi ehk palli ekraanile joonistada ja seal liigutada, siis
alusruudust sobivad kasutada asukoha koordinaadid ja liikumisearvutus, aga
joonistamise tulemusena peaks midagi kandilisest ruudust ümaramat ekraanile
ilmuma. Nii siin teha saabki. Kukkuva palli juures luuakse joonistuskäsklus
uuesti koos ümmarguse ringiga, see asendab ruudu juurest kaasa tulnud kandilise
joonistusfunktsiooni.
Platsi peale pannakse AlusRuut ja Pall mõlemad. Neil olemas nüüd nii joonistus-
kui liikumisoskus. Pall määrab oma liikumissammuks iga kaadriga kaks ühikut
allapoole, alusruudul antakse loomisel paremale liikumise andmed.
Kujundid
Ülesandeid
Pane näide tööle
Lisa mitu ruutu erisuguste kiirustega
Kukkuva palli juures määra kukkumiskiirus juhuslikult vahemikus 1-5 ühikut
kaadri kohta
Lisa katsetamiseks mitu palli.
Klassi prototüübid andmehalduses
Järgnevalt pikem näide, kus eri tegevused eri objektide vahel jaotatud ning
võimaldavad kummalgi tüübil selle jaoks mõeldud tegevusele keskenduda ning
sellega koodi paremini loetavana hoida. Alustuseks luuakse AndmeHalduse tüüp,
kus talletatakse teksti ja arvu paarid ning kust saab hiljem arvud eraldi
funktsiooniga välja küsida.
Kujundid
Näite väljundiks siis kaks arvu:
175,165
Tabelina näitav laiendus
Andmete hoidjale saab vajadust mööda mitmesuguseid andmete kuvajaid peale
ehitada. AndmeTabeli objektis jäetakse meelde teksti ja arvu komplektid. Eraldi
käsuga saab välja küsida ka ainult arvud. Olemasolevale objektile saab peale
ehitada teise.
AndmeTabel.prototype=new AndmeHaldus();
ütleb, et igale uuele AndmeTabelile võetakse aluseks AndmeHalduse eksemplar.
Ehk siis AndmeTabeli objekt oskab samuti enese sisse teksti ja arvu komplekte
koguda ja sealt arve eraldada. Lisaks on tal juures oskus tulemuste kuvamiseks
tabelina.
Kujundid
Tabelit võib lehel vaadata
Ülesandeid
Pane näide tööle
Lisa AndmeTabeli juurde käsk arvude loetelu näitamiseks (unordered list)
Joonisena näitav laiendus
Samale AndmeHalduse tüübile võimalik peale ehitada teine lahendus, sedakorda
joonistusoskusega. Siin kasutatakse arvudena välja küsimise oskust.
Joonistustahvel lisatakse funktsioonis etteantud nimega kihile sedakorda
Javaskripti DOM-funktsioonide abil.
var tahvel=document.createElement("canvas");
tahvel.setAttribute("width", "300");
tahvel.setAttribute("height", "200");
tahvel.style.backgroundColor="yellow";
document.getElementById(kihinimi).appendChild(tahvel);
Üheks mooduseks elementide veebilehele lisamisel on lehe elementide omadus
innerHTML, kuhu kirjutatud väärtused teisendatakse brauseri mälus seal
olevateks objektideks. Samas on aga võimalik ka objektipuud mööda liikuda ja
seal andmeid elemente luua ja ümber paigutada, mis mõnel juhul on mugavam või
kiirem. Sõltumata loomismoodusest saab tahvlit ikka ühtemoodi kasutada.
Kujundid
Tulemusena võibki imetleda andmete graafilist väljundit.
Ülesandeid
Pane näited tööle
Kuva AndmeJoonise tulpade juurde ka nimetused ja arvud