Objekt (programmeerimine)

Informaatikas võib **objekt** olla muutuja, andmestruktuur, alamprogramm või meetod. Nagu ka muude mälupiirkondade puhul, viidetakse objekti sisule identifikaatori abil.

Objektorienteeritud programmeerimise (OOP) paradigma puhul võib objekt koosneda muutujatest, funktsioonidest ja andmestruktuuridest. Klassipõhistes paradigma variatsioonides nimetatakse objektiks klassi instantsi.

Suhetepõhise andmebaasi halduse puhul on objektiks tabel, tulp või suhe andmete ja andmebaasi üksuse vahel (näiteks vanus ja isik).

## Objektipõhised keeled

Keelt nimetatakse objektipõhiseks juhul, kui selle objektid vastavad alljärgnevatele (kehtivuse ja sisalduvuse) nõuetele:
* Identiteet: objektide loomupärane erinevus, isegi võrdväärse sisu korral. 
* Omadused (*properties*): objekti kirjeldavad infokillud, mis on võrreldavad nii andmeväljade kui ka meetoditega. Kuigi süntaktiliselt on objekti omaduse ja andmevälja lugemine ning muutmine eristamatu, transleeritakse omadused *getter* ja *setter* meetodite väljakutseteks.
* Andmeatribuudid: objektil asuvad muutujad. Erinevalt omadustest ei ole atribuudid töödeldav eksklusiivselt *getter* ja *setter* meetodite abil.

## Objektorienteeritud keeled

Keelt loetakse objektorienteerituks, kui see täidab objektipõhise keele nõudeid ning lisaks võimaldab järgmiseid võtteid:
* Polümorfism – funktsioonide ülekoormamine (*overload*), mis võimaldab erinevat käitumist (*behaviour*) sõltuvalt argumentidena edastatud objektidest.
* Pärimine – võimalus luua alamklass (*subclass*), millel on kõik vanema (*parent*) klassi piirangud ja omadused, seejuures võimaldades uue funktsionaalsuse lisamist.

* Kapseldamine – protsess, mis seisneb omavahel seotud andmete ja meetodite ülejäänud programmist abstraheerimises (peitmises) ning välismaailmaga suhtlemiseks liideste loomises.
Vahel nõutakse ka järgmist:
* Kompositsioon – olukord, milles klass sisaldab teisi klasse.

## Objektorienteeritud programmeerimine

Objektorienteeritud programmeerimine on lähenemine, mis tagab modulaarse ja taaskasutatava programmikoodi. Välja on see arenenud headest disaini tavadest, mis on olnud kasutuses juba programmeerimise tekkeaastatel. Oma olemuselt on objektorienteeritus vaid varasemate võtete, näiteks struktureeritud programmeerimise ja abstraktsete andmetüüpide, loomulik edasiareng. Objekt on ei midagi enamat kui abstraktne andmetüüp ühenduses polümorfismi ja pärimisvõimega.

Andmete ja koodi eristamise asemel ühendab objektorienteeritud süsteem need "objekti" mõiste abil. Objekt koosneb olekust (*en:state* ehk andmed) ja käitumisest (en:*behaviour* ehk kood). Objekt võib olla inspireeritud päris maailmast. Nii näiteks e-pood vajab selliseid objekte nagu *ostukorv*, *klient* ja *toode*. Seejuures ostukorv võib sisaldada näiteks käitumist *lisa* ja *telli*, kliendi objektil aga võib olla võimalus *muuta parooli*. Disaini poolest on objektid hierarhilised. Nii võib e-pood vajada üldisemaid klasse nagu *elektroonikatooted* ja *köögitooted*. Kuid tõenäoliselt läheb vaja ka täpsustatud funktsionaalsustega ja omadustega klasse, näiteks *elektroonikatooted* võiksid jaguneda *CD-mängijaks*, *DVD-mängijaks* jne. Sellised klassid ja alamklassid vastavad matemaatilistele hulkadele ja alamhulkadele.

## Spetsiaalsed objektid
Objektide puhul on tähtsaks mõisteks tarkvaraline disaini muster. Selline muster pakub taaskasutatavat malli lahendamaks tihti kohtuvaid probleeme. Alljärgnevalt on välja toodud mõned põhilised objekti disaini mustrid. 

*Funktsiooni objekt (*function object*) – ühtainsat meetodit sisaldav objekt, mis käitub sarnaselt funktsiooniga (sarnaselt C/C++ funktsiooni viitega).
*Muutumatu objekt&emsp;(*immutable object*) – objekt, mille olek (*state*) on fikseeritud loomise protsessis ning on hiljem muutumatu.
*Esimest järku objekt (*first-class object*) – piiranguteta objekt.
*Konteinerobjekt (*container object*) – objekt, mis võib sisaldada teisi objekte.
*Tehasobjekt (*factory object*) – objekt, mille eesmärgiks on luua teisi objekte.
*Metaobjekt (*metaobject*) – objekt, mis võimaldab luua teisi objekte enda põhjal (võrreldav klassiga, mis aga ise ei pruugi objekt olla).
*Prototüüpobjekt (*prototype object*) – spetsialiseeritud metaobjekt, mille põhjal on võimalik luua uusi objekte kopeerimise teel.
*Jumalik objekt (*god object*) – objekt, mis "teab" või teeb liiga palju (näide anti-mustrist).
*Üksik objekt (*singleton object*) – objekt, mis on ainsaks klassi instantsiks terve programmi jooksul.
*Filtriobjekt (*filter object*) – objekt, mis teisendab sisendatud andmevoogu ning tagastab seda. Tihti on sisend- ja väljendvoogudeks märkide vood, kuid nendeks võivad olla ka suvaliste objektide vood. Tegeliku implementatsiooni varjamise ja selle arendajale vajaliku abstraktsiooniga asendamise tõttu kasutatakse seda tihti ümbristes.

## Hajusobjektid

Objektorienteeritud lähenemine ei kujuta endast vaid programmeerimismudelit. See on samuti kasutatav liidest kirjeldava keelena hajussüsteemide jaoks. Hajusarvutuse mudeli puhul kipuvad objektid olema rohmakamad (*larger grained*), pikemalt kasutatavad ja teenustele orienteeritumad kui programmeerimisobjektid.

Hajusobjektide pakendamiseks kasutatakse enamasti liidest defineerivat keelt (*Interface Definition Language*) ehk IDL-i. IDL varjab kliendi eest kõiki hajusserveri detaile. Sellised detailid on näiteks serveri kasutatav programmeerimiskeel ja operatsioonisüsteem. IDL on samuti tihti hajuskeskkonna osaks, mis pakub objektidele transaktsiooni ja püsivuse teenuseid, säilitades seejuures tänu tsentraliseeritusele nende protsesside ühtsust terve programmi vältel. Kaheks enamlevinud hajusobjektide standardiks on Object Management Group'i CORBA standart ja Microsofti DCOM. 

Hajusarvutuse võimaldamiseks on lisaks hajusobjektidele välja pakutud ka muid tavaobjekti laiendusi:
**[[Protokolli objekt]]id* on protokolli virna komponendid, mis sisaldavad võrgu suhtlust, pakkudes seejuures objektorienteeritud liidest.
**[[Replitseeritud objektid]]* on hajusobjektide rühmad ehk *replikad*, mis haldavad hajutatud mitmeosapoolset protokolli, säilitamaks järjepidevust nende olekute vahel ning mis käsitlevad taotlusi koordineeritud moel. Üheks selliseks näiteks on vigasid taluv CORBA objekt.
**[[elav hajutatud objekt|Elavad hajusobjektid]]* (või lihtsalt *elavad objektid*) on *replitseeritud objektide* üldistuseks, mis võivad sisemiselt kasutada suvalist hajusprotokolli, seejuures tõenäoliselt säilitades vaid vähest järjepidevust nende siseseisundite vahel.

Mõned neist laiendustest, nagu *hajusobjektid* ja *protokollobjektid*, on valdkonnaspetsiifilised mõisted kirjeldamaks tavaobjektide eritüüpe mõnes konkreetses kontekstis (näiteks meetodi kaugväljakutse või protokolli struktuur). Teised aga, näiteks *replitseeritud objektid* ja *elavad objektid*, on tunduvalt ebastandartsemad. Erinevalt tavaobjektidest, mis asetsevad vaid ühes kohas, rakendavad nad objekti mõiste *replikate* grupile. Lisaks võib nende seisund olla ebapidev ning kuuluvus dünaamiliselt muutuda.

## Semantiline veeb

Oma olemuselt on semantiline veeb hajusobjektide raamistikuks (*framework*). Kaheks põhitehnoloogiaks selle kontekstis on veebi ontoloogia keel (*Web Ontology Language* ehk OWL) ja ressursse kirjeldav raamistik (*Resource Description Framework* ehk RDF). OWL laiendab objekti mudelit toetudes hulgateooriale lisades seeläbi uusi modelleerimisvõimalusi, näiteks mitmekordne pärimine. RDF aga pakub võimalust defineerida põhilisi objekti nimesid, omadusi, atribuute ja suhteid, mis oleksid kättesaadavad interneti teel.

OWL-i objektid pole sarnased IDL-i teel kättesaadavate rohmakate hajusobjektidega. Interneti puhul poleks selline ühe liideste (*interface*) kimbu standartiseerimine sobivaks lähenemiseks. Ning seda eeskätt interneti pideva arengu ja muutumise tõttu. OWL-i objektid kipuvad sarnanema pigem nendega, mis on kasutusel rakenduste (*applications*) arendamisel näiteks keeltes Java ja C++.

Sellele vaatamata pole OWL-i ja tavalised objektorienteeritud programmeerimise objektid siiski täiesti ühesugused. Erinevalt traditsioonilistest objektidest, mis kompileerimise järgselt muutuvad staatilisteks struktuurideks, seejuures pärides tavaliselt vaid ühest allikast, on OWL-i objektid dünaamilised. Selline objekt võib muuta oma struktuuri programmi käigus ning muutuda lisa- või uute klasside instantsiteks.

Teine tähelepanuväärne erinevus on süsteemis puuduva informatsiooni kohtlemine. Tavaliste programmeerimisobjektide ja enamuse andmebaasi süsteemide puhul on kasutusel "suletud maailma eeldus": kui väide pole süsteemile tuttav, loetakse seda vääraks. Semantilise Veebi objektid kasutavad seevastu "avatud maailma eeldust": väidet loetakse vääraks vaid juhul, kui selleks on süsteemis vastav infokild, vastasel juhul loetakse seda teadmatuks, mis ei ole ei tõene ega väär.

Kõige enam sarnanevad OWL-i objektid tehisintellekti freim keeltega, näiteks KL-ONE ja Loom.

Järgnev tabel võrdleb objektorienteeritud keelte (näiteks Java ja C++) ning Semantilise Veebi objekte: 

## Näiteid programmeerimiskeeltest

### Python


```python
class Koduloom:
    def __init__(self, nimi):
        self.nimi = nimi

class Papagoi(Koduloom):
    def __init__(self, nimi):
        super().__init__(nimi)
    def liigu(self):
        print("Ma lendan!")


minu_papagoi = Papagoi("Kesha")

print("Mu nimi on " + minu_papagoi.nimi)
minu_papagoi.liigu()
```



```text
Mu nimi on Kesha
Ma lendan!
```


### JavaScript


```javascript
class Koduloom {
  constructor(nimi) {
    this.nimi = nimi;
  }
}

class Koer extends Koduloom {
  constructor(nimi) {
    super(nimi);
  }

  tee_häält() {
    console.log("Ma haugun!");
  }
}

minu_koer = new Koer("Sharik");

console.log("Mind hüütakse " + minu_koer.nimi);
minu_koer.tee_häält();
```



```text
Mind hüütakse Sharik
Ma haugun!
```


### C++


```c++
#include <string>
#include <iostream>

class Koduloom
{
public:
    std::string nimi;
    Koduloom(std::string nimi_)
    {
        nimi = nimi_;
    }
};

class Kass : public Koduloom
{
public:
    Kass(std::string nimi) : Koduloom(nimi) {}
    void hüppa()
    {
        std::cout << "Ma hüppan!" << std::endl;
    }
};

int main()
{
    Kass minu_kass("Matroskin");

    std::cout << "Mu nimeks " << minu_kass.nimi << "!" << std::endl;
    minu_kass.hüppa();

    return 0;
}
```



```text
Mu nimeks Matroskin!
Ma hüppan!
```


## Vaata ka
*Objektorienteeritud programmeerimine
*Klassipõhine objektorienteeritud programmeerimine
*Klass (programmeerimine)

## Viited