# Olio-ohjelmointi

|  |
| --- |
| **Ohjelmointiparadigmat** |
| Deklaratiivinen ohjelmointi |
| Epärakenteellinen ohjelmointi |
| Funktionaalinen ohjelmointi |
| Geneerinen ohjelmointi |
| Imperatiivinen ohjelmointi |
| Logiikkapohjainen ohjelmointi |
| Olio-ohjelmointi
* Luokkapohjainen ohjelmointi
* Prototyyppipohjainen ohjelmointi
 |
| Proseduraalinen ohjelmointi |
| Rakenteinen ohjelmointi |
| Reaktiivinen ohjelmointi |
| Rinnakkaisohjelmointi |

**Olio-ohjelmointi** (engl. *object-oriented programming*, OOP) on ohjelmoinnin ohjelmointiparadigma, jossa ohjelmointiongelmien ratkaisut jäsennetään olioiden yhteistoimintana.

Oliot sisältävät niiden oman sisäisen tilan (kapselointi) sekä julkisen rajapinnan. Olio-ohjelmointi voi olla:

* luokkapohjaista: oliot saavat tilan ja toiminnallisuuden luokan jäsenien mukaan
* prototyyppipohjaista: oliot saavat toiminnallisuuden prototyyppioliolta

Luokkapohjaisessa ohjelmoinnissa luokat määritellään etukäteen ja oliot luodaan näiden luokkien perusteella, jolloin oliot saavat tilan ja toiminnallisuuden luokan jäsenten mukaan. Esimerkiksi jos kaksi oliota, kuten kissa ja koira, toteutetaan luokasta Eläin, niin ne ovat luonnollisesti eläimiä ja niitä voidaan käsitellä samalla tavalla. Tämä tarkoittaa sitä, että näillä eläinolioilla on samat ominaisuudet.

Prototyyppipohjaisessa olio-ohjelmoinnissa oliot saavat toiminnallisuuden ja ominaisuudet prototyyppioliolta eikä luokkia ole edes olemassa. Olion prototyyppi on vain toinen olio, johon olio on linkitetty. Jokaisella oliolla on vain yksi prototyyppilinkki. Uusia olioita voidaan luoda niiden prototyypeiksi valittujen jo olemassa olevien olioiden perusteella. Kahta eri oliota, kissa ja koira, voi kutsua eläimiksi, jos eläinolio on olemassa ja se on sekä kissan että koiran prototyyppi. Voidaan sanoa eläinluokan olevan saman prototyypin jakavien olioiden ekvivalenssiluokka. Prototyypin ominaisuudet ja metodit delegoituvat kaikille tämän prototyypin määrittämän ekvivalenssiluokan olioille. Olion omistamia yksilöllisiä ominaisuuksia ja metodeja ei saa jakaa muiden saman ekvivalenssiluokan olioiden kanssa. Prototyypin kautta voidaan toteuttaa vain yksi perimä, joka tapahtuu prototyypin kautta.

Olio-ohjelma muodostuu kokoelmasta yhteistyössä toimivia olioita, kun taas perinteinen proseduraalinen tietokoneohjelma on lista suoritettavia ohjeita tietokoneelle.

Olio-ohjelmoinnissa tieto ja sitä käsittelevä toiminnallisuus tyypillisesti kootaan yhteen tietorakenteeksi, jota kutsutaan *olioksi*. Olio käsittelee sisältämäänsä tietoa ja voi vastaanottaa viestejä ja lähettää tietoa muille olioille. Jokainen olio voidaan nähdä itsenäisenä pienenä koneena, jolla on tietty rooli tai vastuu.

Olio-ohjelmointi on kehitetty helpottamaan ja selkeyttämään yhä monimutkaisemmiksi tullutta ohjelmistojen kehittämistä ja ylläpitoa. Olio-ohjelmoinnin yhtenä tavoitteena on tehdä ohjelmistojen laajentamisesta ja ylläpidosta helpompaa. Yksittäinen olio vastaa jostakin itsenäisestä osa-alueesta ohjelman kokonaisuudessa. Olio on merkityksellinen myös irrotettuna välittömästä asiayhteydestään, jolloin sitä voidaan käyttää myös uusissa asiayhteyksissä. Oliota käyttävän tarvitsee vain tietää, mihin tarkoitukseen olio on suunniteltu ja miten sitä pitää käyttää. Koska yhden pienen olion sisäinen ohjelmakoodi on lyhyt, se on yleensä helpommin ymmärrettävissä ja ylläpidettävissä.

Tietokoneohjelmat voivat hyödyntää olioita monella tapaa. Puhtaissa oliokielissä kaikki kielen alkiot ovat olioita. Useat ohjelmointikielet, kuten C++ sallivat olioiden käyttämisen yhdessä perinteisen ohjelmointimallin sisällä. Oikein käytettynä olio-ohjelmointi nopeuttaa kehitystyötä, vähentää redundanssia, ohjelmointivirheitä ja helpottaa merkittävästi ohjelmistojen ylläpitoa. Nykyaikaisten tietokoneohjelmien kehittämisessä olio-ohjelmointi on yksi tärkeimmistä työkaluista. Suosittuja olio-ohjelmointia tukevia kieliä ovat muun muassa C++, C#, Java, Python ja Visual Basic.

Merkittäviä oliokieliä ovat: Ada, ActionScript, C++, Common Lisp, C#, Dart, Eiffel, Haxe, Java, JavaScript, Kotlin, logo, MATLAB, Objective-C, Object Pascal, Perl, PHP, Python, R, Ruby, Scala, Simula, Pharo, Smalltalk ja Swift.

## Käsitteitä

Olio (engl. *object*) on ohjelmiston rakenteellinen perusyksikkö. Se ei ole puhtaasti toiminnallinen tai puhtaasti tietoa säilyttävä, vaan se sisältää kummankin aspektin.

Olio-ohjelmointi jakautuu kahteen pääsuuntaukseen. Smalltalkin sanastossa oliot kommunikoivat keskenään lähettämällä ja vastaanottamalla *viestejä*. Viestin vastaanottaminen suorittaa määritellyn toiminnon vastaanottavassa oliossa.
Simulan tai C++:n sanastossa oliot kutsuvat toisensa *jäsenfunktioita*.

Oliota käytetään ohjelmistosuunnittelussa esittämään jonkun abstraktin tai reaalimaailman käsitteen ilmentymää ohjelmistossa. Oliokielillä laaditut ohjelmat koostuvat tavallisesti lukuisista olioista, joiden yhteistoiminnan tuloksena on ratkaisu ohjelmointiongelmaan. (kts. myös oliomalli)

Olio pystyy pyydettäessä tekemään sille ominaiset toiminnot, joita kutsutaan *metodeiksi* tai *jäsenfunktioiksi* kielestä riippuen. Metodi koostuu nimestä, mahdollisista parametreista ja toiminnan määrittelevästä rungosta. Olio tallettaa tietoja attribuutteihin.

Luokka (*class*) on määritelmä, joka kuvaa samanlaisten olioiden yhteisen rakenteen ja yhteisen käytöksen. Toisin sanoin luokka on ohje olion luomiselle ja sitä voidaan pitää olion tyyppinä. Olio on siten luokan ilmentymä, instanssi. Esimerkiksi henkilörekisteriohjelmassa määritellään luokka Henkilö, joka määrittelee millaista tietoa henkilöistä halutaan esittää ja millä tavalla näitä tietoja voidaan käsitellä. Ohjelman ajon aikana luokasta Henkilö luodaan olioita esittämään yksittäisiä henkilöitä. Olioiden toiminnallisuus määritellään useimmiten luokkien jäsenfunktioissa, jolloin kaikki saman luokan oliot sisältävät täsmälleen saman toiminnallisuuden tiedon käsittelyyn. On olemassa myös vähemmän tunnettuja prototyyppipohjaisia kieliä, jotka eivät tunne luokkakäsitettä.

Sidonta (*binding*) tarkoittaa sitä, miten symbolinen nimi yhdistetään dataan tai koodiin. Kaksi tapaa ovat myöhäinen ja varhainen sidonta. Joko kääntäjä tekee sen käännöksen yhteydessä, jolloin puhutaan staattisesta (*varhainen*) sidonnasta, tai se tapahtuu ajonaikana, jolloin kyseessä on dynaaminen (*myöhäinen*) sidonta. Jossain tilanteissa objektin tyyppi ei ole tiedossa vielä käännösaikana, jolloin on käytettävä dynaamista eli myöhäistä sidontaa.

Perintä (*inheritance*) mahdollistaa uusien luokkamääritysten tekemisen vanhojen määritysten pohjalta. Periyttämisen ansiosta on mahdollista käyttää uudestaan jo tehtyä ohjelmakoodia uusien luokkien pohjana. Periyttäminen mahdollistaa myös abstraktien perus-/kantaluokkien, joista periytetään useita luokkia, joita kaikkia voidaan käyttää samannimisillä funktioilla ja samoilla parametreilla kuin abstraktia kantaluokkaa, käytön. Itse abstraktista kantaluokasta ei voi luoda omia instansseja eli olioita new-operaattoria käyttäen. Oliot on luotava tässä tapauksessa abstraktin luokan lapsiluokista. Esimerkkinä abstrakti luokka voisi olla ajoneuvot-luokka, jolla olisi vuosimalli jäsenmuuttujana ja funktiona/metodina "rekisteröi"-toiminto. Lapsiluokkia voisivat olla esimerkiksi auto- ja laiva-lapsiluokat, jotka perivät ajoneuvoluokan jäsenmuuttujat ja funktiot. Perinnässä tärkeä huomionarvo on myös kantaluokan näkyvyysmääreiden asettaminen. Tämä johtunee siitä, että kantaluokan "private"-nimikkeellä määritetyt jäsenmuuttujat ja funktiot eivät periydy alempiin luokkiin. Näkyvyysmääreeksi on asetettava vähintään "protected", jotta lapsiluokka perii kyseisen jäsenmuuttujan tai funktion onnistuneesti. Periyttäminen ja abstraktien perusluokkien käyttö ovat oliopohjaisten kielien vahvimpia mutta myös vaikeimpia ominaisuuksia. Periyttäminen mahdollistaa abstraktit rajapinnat, joiden kautta voidaan käsitellä tuntemattomien tahojen rakentamia olioita ennalta määritellyllä tavalla.

Moniperintä (*multiple inheritance*), mahdollistaa uuteen luokkaan periyttämisen useista kantaluokista. Moniperintä on hyödyllistä tilanteessa, jossa "lepakko" sisältää "lentävä eläin"- ja "nisäkäs"-luokkien ominaisuudet. Moniperintä on tuettu kielissä kuten C++, Eiffel, OCaml ja Scala. C++ tukee *virtuaalista moniperintää*, jonka avulla periytyy vain yksi toteutus yhteisen kantaluokan jäsenistä. Kaikissa oliokielissä moniperintä ei ole mahdollista.
Eräissä kielissä moniperintä on vain rajatusti mahdollista. Rajattua moniperintää (*interface* eli rajapintaperintää) tukevat kielet kuten Ada, C# ja Java. JavaScript käyttää perimisen toteuttamiseen *prototyyppejä*.

Kapselointi *(encapsulation)* -termiä käytetään kahdessa merkityksessä. Ensimmäisen merkityksen mukaan kapseloinnin ideana on datan ja käyttäytymisen kokoaminen yhteen yksikköön, olioon. Toinen merkitys lisää tähän vielä tiedonpiilotuksen: olion sisäisiin muuttujiin ei (pääsääntöisesti) päästä suoraan käsiksi olion ulkopuolelta, jolloin ohjelmointivirheiden määrä vähenee.
Olion käyttäjän ei tarvitse tietää enää käyttövaiheessa sitä, miten olio toimii sisäisesti: riittää, kun tietää, miten oliota itseään käytetään ja miten olio *käyttäytyy*. Olion käyttäjät voivat käyttää oliota sen julkisen rajapinnan kautta (public interface). Olion luokkakuvauksessa voi olla myös yksityisiä muuttujia tai funktiota (private interface), jotka ovat vain olion itsensä käytettävissä.

Konstruktori (*constructor*, rakentaja) on metodi, joka alustaa luokan ilmentymät. RAII-konseptissa konstruktori myös varaa resurssit, jotka vapautetaan destruktorissa.

Destruktori (*destructor*, hajottaja tai purkaja) on metodi, joka vapauttaa olion varaamat resurssit.

Polymorfismi eli monimuotoisuus tarkoittaa sitä, että yhtä rajapintaa käytetään eri tyyppien käsittelyyn, tai yksi symboli edustaa monia tyyppejä. Esimerkiksi funktio tai datatyyppi voidaan kirjoittaa siten, että se voi käsitellä dataa riippumatta sen tyypistä.

Virtuaalimetodi on ominaisuus, jolla perintää käyttävä olio voi korvata yliluokassa olevan metodin toteutuksen toisella.

Luokkafunktiot esittävät luokan palveluja sekä operaatioita, jotka eivät kohdistu yksittäiseen olioon. Jos jäsenfunktiot ovat samankaltaiset määrittelyn kanssa lisätään static-avainsana, ei voida käyttää olemassa olevan olion jäsenmuuttujia eikä this-avainsanaa ja voi käyttää luokkamuuttujia. Luokalla voi olla useampi luokkafunktio, eikä luokkamuuttujan tarvitse aina olla julkinen.

Abstrakti luokka (Abstract class) on yksi olio-ohjelmoinnin peruskäsitteistä, joka mahdollistaa yleisten ominaisuuksien ja toimintojen jakamisen eri luokkien välillä. Abstrakti luokka ei pysty luomaan olioita, mutta se voi sisältää yhden tai useamman abstraktin metodin. Abstrakti metodi on määritelty luokassa, mutta sille ei ole toteutusta. Abstrakti luokka toimii pohjana lapsiluokille, joissa ne pitää toteuttaa.

Singleton (ainokainen) on suunnittelumalli, joka varmistaa että tietyn luokan oliolla on vain yksi instanssi ja että kaikkilla osilla on pääsy tähän samaan instanssiin. Singleton toteutetaan yleensä staattisella metodilla, joka palauttaa saman instanssin jokaiselle kutsujalle. Singleton on hyödyllinen erityisesti silloin, jos halutaan varmistaa että luokalla on vain yksi käyttötapaus.

Perintö (inheritance) on keskeinen olio-ohjelmoinnin käsite, joka tarkoittaa sitä, että uusi luokka voi periä vanhemman luokan toimintoja tai ominaisuuksia. Perintö auttaa koodin järjestelyssä ja ylläpitämisessä ja mahdollistaa sen uudelleenkäytön, jos niin halutaan.

Rajapinta (interface) on määritelmä siitä, miten luokka kommunikoi ja toimii muiden luokkien kanssa. Rajapinta määrittelee, mitä toimintoja ja ominaisuuksia luokka tarjoaa muille luokille. Rajapinta mahdollistaa erilaisten luokkien yhteensopivuuden ja helpottaa koodin ylläpitoa. Rajapinta ei siis ole itse toteutus vaan kertoo pelkästään, mitä toimintoja luokalla on. Rajapinnan toiminnot täytyy määritellä erikseen niissä luokissa, jotka käyttävät tätä pintaa.

## Esimerkki

Pseudokielinen esimerkki luokkakuvauksesta luokalle "Oppilas":

```
 // Aloitetaan kantaluokan määrittely
 class Henkilö {
 protected:
     String nimi; // yhteinen jäsenmuuttuja kaikille henkilöille

 public:
    function asetaNimi( String nimi) {
        this.nimi = nimi;
    }
 }

 // Periytetään luokka Opettaja kantaluokasta.
 class Opettaja inherits Henkilö {
 public:
     function haeTitteli() {
         return "prof. " + this.nimi;
     }
 }

 // Periytetään luokka Opiskelija kantaluokasta
 class Opiskelija inherits Henkilö {
 private:
     int arvosana; // sisäinen muuttuja, jota ainoastaan olio itse voi käsitellä

 // tästä eteenpäin kirjoitetut julkiset tiedot ovat kaikkien käytettävissä
 public:
     function asetaArvosana(int uusiArvosana) {
         this.arvosana = uusiArvosana; // laitetaan parametri "uusiArvosana" sisäiseen muuttujaan "arvosana"
     }

     function haeArvosana() {
         return this.arvosana;   // palautetaan sisäisen muuttujan "arvosana" arvo
     }

     function haeTitteli() {
         return "tekn. yo. " + this.nimi;
     }
 }

```

Esimerkki olion käytöstä:

```
 // Tehdään kaksi oliota "harri" ja "pekka"
 // HUOM! Jokaisella uudella oliolla on omat yksityiset muuttujansa
 harri = new Opiskelija();
 pekka = new Opiskelija();

 prof = new Opettaja();
 prof.asetaNimi("Tuumivainen");

 harri.asetaArvosana(5);
 harri.asetaNimi( "Harri Hakkeri" );
 pekka.asetaArvosana(4);

 // Tulostaa: Harrin arvosana on 5 ja Pekan on 4
 print "Harrin arvosana on " + harri.haeArvosana() + " ja Pekan on " + pekka.haeArvosana();
 // Tulostaa: opettaja oli: prof. Tuumivainen
 print "opettaja oli: " + prof.haeTitteli();
 // Tulostaa: opiskelija oli: tekn.yo. Harri Hakkeri
 print "opiskelija oli: " + harri.haeTitteli();

```

## Historia

### Ensimmäiset kielet

Terminologia, joka liittyy "olioihin" ja "orientaatioon" modernissa mielessä oliopohjaisessa ohjelmoinnissa, ilmestyi ensimmäisen kerran MIT:ssä 1950- ja 1960-lukujen vaihteessa. Jo vuodesta 1960 lähtien tekoälyä tutkivan ja kehittävän ryhmän yhteydessä "olio" saattoi viitata tunnistettuihin kohteisiin (LISP-atomeihin), joilla oli ominaisuuksia (attribuutteja). Olioperustainen ohjelmointi syntyi Norjassa 1960-luvun jälkipuoliskolla, jolloin norjalaisessa Norsk Regnesentral -laskentakeskuksessa kehitettiin ensimmäinen oliokieli, Simula. Ole-Johan Dahl ja Kristen Nygaard kehittivät kieltä simulointitarkoituksiin. Jo vuonna 1961 kehitetyssä Simula I:ssa käytettiin luokkia ja niistä luotuja olioita, mutta vuonna 1967 Simula I:n seuraaja Simula67 oli ensimmäinen varsinainen olio-ohjelmointikieli. Simulan rungon muodosti Algol60, joka oli laajennettu olio-ohjelmoinnin luokkakäsitteellä. Simulassa oli mukana jo kaikki olio-ohjelmoinnin peruskäsitteet.

Simula ei saanut paljoakaan käyttäjiä yliopistojen ulkopuolelta. Olio-ohjelmointi sai uutta kantavuutta Smalltalkin ja siihen liittyvän graafisen ohjelmointiympäristön myötä. Smalltalk kehitettiin Xeroxin kehityslaboratoriossa, Palo Alto Research Centerissä (PARC). Sitä käytettiin Alan Kayn ideoiman graafisella käyttöliittymällä varustetun henkilökohtaisen tietokoneen Dynabookin hallintaan. Xerox alkoi jakaa Smalltalkia 1980, mutta sekään ei saavuttanut merkittävää asemaa ohjelmistotuotannossa.

Niin kutsutun ohjelmistokriisin takia 1970-luvulla syntyi useita kieliä, joissa ohjelmistojen modularisointi oli keskeisenä ajatuksena. Kielet eivät olleet tiukassa mielessä olioperustaisia, mutta niihin kuului abstraktin tietotyypin käsite, joka on oleellinen myös olio-ohjelmoinnissa. Nämä kielet loivat maaperää olioperustaisen ohjelmoinnin läpimurrolle tuomalla tietoabstraktion ohjelmistokehitykseen.

Vuonna 1981 Goldberg toimitti Byte Magazinen elokuun numeroa esitellen Smalltalkin ja olio-ohjelmoinnin laajemmalle yleisölle. Vuonna 1986, the Association for Computing Machinery järjesti ensimmäisen konferenssin “Conference on Object-Oriented Programming, Systems, Languages, and Applications (OOPSLA), joka käsitteli olio-ohjelmointia, järjestelmiä ja kieliä. Yllättäen konferenssiin osallistui tuhat ihmistä. 1980-luvun puolivälissä Brad Cox kehitti Objective-C. Hän oli käyttänyt Smalltalkia ITT Inc.:ssä, ja Bjarne Stroustrup, joka oli käyttänyt Simulaa väitöskirjassaan, kehittivät olio-ohjelmointikieli C++:n. Vuonna 1985, Bertnard Meyer myös tuotti ensimmäisen Eiffel kielen mallin. Keskittyen ohjelmiston laatuun, Eiffel oli puhdas olio-ohjelmointikieli ja merkintä tukien koko ohjelmiston elinkaarta. Meyer kuvaili Eiffelin ohjelmistokehitysmenetelmää perustuen pieneen määrään pääideoita ohjelmistosuunnitelusta ja tietokonetieteestä kirjassa Object-Oriented Software Construction. Eiffelin keskittyminen laatuun on olennainen osa Meyerin luotettavuus mekanismia, Design by Contract, joka on olennainen osa molempia, sekä menetelmiä, että kieltä.

1990-luvun alussa ja puolivälissä olio-ohjelmoinnista oli tullut vallitseva tapa ohjelmoida, kun kielet alkoivat tukea tekniikaa. Eri kielet, jotka tukivat olio-ohjelmointia olivat mm. C++ and Delphi. Sen dominointia edisti edelleen graafisten käyttöliittymien suosion kasvu, joka nojaa vahvasti olio-ohjelmoinnin tekniikoihin. Esimerkki läheisesti liittyvästä dynaamisesta käyttöliittymäkirjastosta ja OOP-kielestä löytyy Mac OS X:n Cocoa viitekehyksestä, joka on kirjoitettu Objective-C:llä. Cocoa on dynaaminen oliosuuntautunut viestintälaajennus C:hen, pohjautuen Smaltalkiin. OOP-työkalusarjat lisäsivät myös tapahtumapohjaisen ohjelmoinnin suosiota (vaikkakin tämä konsepti ei rajoitu ainoastaan OOP:iin).

Viime aikoina on myös ilmaantunut useita kieliä, jotka ovat pääosin oliopohjaisia, mutta yhteensopivia proseduraalisten ohjelmointikielien kanssa. Python ja Ruby ovat esimerkkejä tällaisista. Luultavasti kaupallisesti tärkeimmät viimeaikaiset ohjelmointikielet ovat Java, jonka on kehittänyt Sun Microsystems, sekä C# ja Visual Basic.NET (VB.NET), jotka molemmat on kehitetty Microsoftin .NET-alustalle. Kumpikin näistä kahdesta viitekehyksestä osoittaa omalla tavallaan oliopohjaisen ohjelmoinnin käytön edut luomalla abstraktion implementoinnista. VB.NET ja C# tukevat kieltenvälistä periytymistä, jolloin yhdellä kielellä määritellyt luokat voivat siirtyä toisella kielellä määritettyihin aliluokkaluokkiin.

### Läpimurto

Olioperustainen ohjelmointi teki läpimurtonsa 1980-luvun puolivälissä, kun useat tahot kehittivät olioperustaisia kieliä, ohjelmistojen suunnittelumenetelmiä ja niitä tukevia CASE-välineitä sekä yksittäisiä sovelluksia. Lisäksi kiinnostuksen kasvu näkyi uusissa olioperustaisuutta käsittelevissä konferenssisarjoissa, lehdissä ja kirjoissa. Ensimmäinen tuotantokäytössä yleistynyt ohjelmointikieli oli C++. Bjarne Stroustrup kehitti sen Bell Labs -tutkimuskeskuksessa. Vuonna 1980 julkaistu versio oli kehitetty C-kielestä, johon oli lisätty oliotuki. Stroustrup kutsui sitä nimellä ”C with classes”. Kieli otettiin 1983 käyttöön myös Bell Labsin ulkopuolella, jolloin Rick Mascitti keksi nimen C++. Kielen kehittämisen motiivina oli alkuun saada simulointisovelluksiin Simulaa tehokkaampi kieli. Uuden kielen pohjaksi valittiin C, koska se oli suhteellisen matalan tason ohjelmointikieli ja sille oli valmiina toteutuksia lähes kaikissa ympäristöissä. C++ kehittyi vielä voimakkaasti 1980-luvun aikana: siihen lisättiin muun muassa moniperintä, parametrisoidut tyypit ja poikkeusten käsittely. Borland lisäsi omaan Turbo Pascal -kehitysympäristöönsä olio-ohjelmoinnin mahdollisuuden vuonna 1986 (Macintosh-versio). MS-DOS versio julkaistiin vuonna 1989.

Java-ohjelmointikielen kehitys lähti liikkeelle 1990-luvun alkupuolella, kun tarvittiin luotettavia ohjelmistoja erilaisille mahdollisesti verkkoon kytketyille elektronisille laitteille. Sun Microsystemsillä toiminut ryhmä halusi kehittää tarkoitukseen oman kielensä. Ryhmä tutki ensin C++:n käyttöä, mutta he totesivat sen monissa tapauksissa epätarkoituksenmukaiseksi. Java kehitettiin C++:n pohjalta, ja sen pääasiallisin kehittäjä oli James Gosling. Siitä poistettiin monia C++-kielessä virheitä aiheuttavia ominaisuuksia, kuten moniperintä. Sun Microsystemsin ryhmä alkoi 1994 tutkia Javan sopivuutta verkkosovelluksiin, ja keväällä 1994 yritys julkisti Javan lisäksi HotJava-selaimen. Java alkoi tämän jälkeen levitä verkossa, ja uusia Java-ohjelmistoja ilmestyi nopeaan tahtiin. Microsoftkin ilmoitti vuoden 1995 lopulla lisäävänsä ohjelmistoihinsa Java-tuen.

Python-kieli on tullut suosituksi vuosituhannen vaihteen jälkeen. Python on tulkattu ja dynaamisesti tyypitetty ohjelmointikieli, jossa tyyppitarkastukset tehdään ajon aikana. Pythonia pidetään varsin puhdasoppisena oliokielenä ja se on rakenteeltaan yksinkertainen. Pythonia käytetään eniten pienimuotoisten prototyyppien nopeaan kehitykseen.

2000-luvulla on syntynyt ainakin yksi uusi merkittävä oliokieli. Javaa hyvin paljon muistuttava C# on Microsoftin vuonna 2002 lanseeraama .NET-alustassa käytettävä kieli. Toinen Microsoftin .NET alustalle lanseerattu oliopohjainen kieli on Visual Basic.NET (VB.NET). Kumpikin näistä kahdesta .NET -alustan ohjelmistokehysratkaisusta osoittaa omalla tavallaan olio-ohjelmoinnin käytön hyödyn luomalla abstraktioita toteutuksesta. VB.NET ja C# tukevat kielten välistä periytymistä, jolloin toisella kielellä määritellyt luokat voivat periytyä toisella kielellä määritellyistä luokista.

### Nykypäivä

Olio-ohjelmointi nykypäivänä on yksi ohjelmointialan tärkeimmistä työkaluista, joka auttaa kehittäjiä luomaan tehokkaampia, joustavampia ja helpommin ylläpidettäviä ohjelmistoja. Se on laajalti käytössä monissa ohjelmointikielissä, kuten Java, C++, C# ja Python, ja se tarjoaa ohjelmoijille kätevän tavan organisoida ja hallita koodiaan.

Olio-ohjelmoinnin perusperiaatteisiin kuuluvat kapselointi, periytyminen, polymorfismi ja abstraktio. Nämä käsitteet auttavat ohjelmoijia kehittämään modulaarisia ohjelmistoja, joissa eri osat ovat itsenäisiä ja helposti korvattavissa tai laajennettavissa. Tämä mahdollistaa paremman koodin uudelleenkäytön ja parantaa ohjelmistojen ylläpidettävyyttä.

Nykypäivän ohjelmistokehitysprojekteissa olio-ohjelmointi on erityisen tärkeässä roolissa, kun luodaan monimutkaisia ja laajoja järjestelmiä, kuten pilvipalveluita, älypuhelinsovelluksia, tekoälyjärjestelmiä ja esineiden internet -ratkaisuja (IoT). Olio-ohjelmointi tekee koodin organisoinnista selkeämpää, mikä auttaa kehittäjiä työskentelemään tehokkaammin yhdessä ja hallitsemaan järjestelmän monimutkaisuutta.

Olio-ohjelmoinnin käyttö on lisääntynyt erityisesti ohjelmistokehityksen ketterien menetelmien yleistyessä. Scrum, Kanban ja muut ketterät menetelmät korostavat iteratiivista ja inkrementaalista kehitystä, mikä edellyttää koodin joustavuutta ja modulaarisuutta. Olio-ohjelmointi tukee näitä vaatimuksia tarjoamalla selkeät rakenteet ja työkalut koodin organisointiin ja muokkaamiseen.

Lisäksi olio-ohjelmoinnin merkitys kasvaa jatkuvasti, kun ohjelmistoalalla otetaan käyttöön uusia teknologioita ja menetelmiä, kuten pilvipohjaiset mikropalveluarkkitehtuurit, konttiteknologiat, kuten Docker ja Kubernetes, ja hajautetut sovellusalustat, kuten blockchain. Näissä konteksteissa olio-ohjelmointi tarjoaa kehittäjille välttämättömät välineet sovellusten rakentamiseen, jotka ovat helposti skaalattavissa, ylläpidettävissä ja integroitavissa.

Olio-ohjelmoinnin käytön leviäminen on johtanut uusien kehitysympäristöjen ilmentymiseen, jotka tuovat ohjelmoijille lisää uusia työkaluja koodin testaamiseen. Monissa integroiduissa kehitysympäristöissä, kuten Visual Studio, on valmiiksi sisäänrakennettuja työkaluja, jotka tukevat olio-ohjelmointia. Näitä työkaluja ovat esimerkiksi debugger ja automaattinen koodin generointi.

Olio-ohjelmointi on myös tärkeässä asemassa ohjelmistojen tietoturvan osalta. Sen avulla kehittäjä voi esimerkiksi piilottaa joitakin ohjelmiston toiminnallisuuksia ulkopuolisilta, mikä auttaa suojaamaan tietoja. Olio-ohjelmointi myös helpottaa ohjelmistojen testausta, mikä johtaa parempaan laatuun.

Nykypäivänä olio-ohjelmointiin liittyy jatkuvaa kehitystä sekä tutkimusta, ja uusia menetelmiä ja tekniikoita kehitetään jatkuvasti sen parantamiseksi. Tähän liittyy esimerkiksi ohjelmointikielten kehityksen, suorituskyvyn optimoimisen ja uusien menetelmien kehittämisen olio-ohjelmointia varten.

Olio-ohjelmointi on avannut uusia mahdollisuuksia ohjelmistokehittäjille parantamaan käyttäjäkokemusta. Ohjelmoijat voivat esimerkiksi käyttää olioita luodakseen entistä kattavampia käyttöliittymiä, joihin liittyy esimerkiksi erilaisia animaatioita ja toimintoja.

Lisäksi olio-ohjelmointi on ollut tärkeässä roolissa pelinkehityksessä. Oliot ovat peleissä keskeisiä, sillä ne mahdollistaa objektien ja pelihahmojen luomisen. Pelialan lisäksi olio-ohjelmointi on ollut tärkeässä asemassa myös esimerkiksi terveysalan ohjelmistokehityksessä, jossa vaaditaan luotettavuutta ja turvallisuutta. Olio-ohjelmointi on tarjonnut kehittäjille erilaisia apuvälineitä ja tekniikoita, joita käyttäen voidaan luoda aina vain parempia ja monipuolisempia ohjelmistoja erilaisiin käyttötarkoituksiin.

## Periaatteita

Abstraktio tarkoittaa kokonaisuuksien käsittelyä, jossa tarkennetaan vain tarvittaessa. Kokonaisuuksien hahmotus katoaa, kun alamme lisäämään yksityiskohtia. Abstraktio on tällöin juuri yksityiskohtien piilottamista, jotta kokonaiskuvaa parannee. Tätä tiedon piilottamista kutsutaan olio-ohjelmoinnissa kapseloimiseksi.

Kapselointi on attribuuttien ja metodien sitomista yhteen luokassa. Kapseloinnin avulla luokan sisäiset yksityiskohdat voidaan piilottaa ulkopuolisilta. Luokalla on metodeja, jotka tarjoavat käyttöliittymiä, joiden avulla luokan tarjoamia palveluita voidaan käyttää. Kapselointi estää ulkoista koodia käsittelemästä olion sisäistä toimintaa, eli olio tarjoaa palvelut ainoastaan rajapintansa kautta, jolloin olion luokan sisäisellä toiminnalla ei ole merkitystä, kunhan metodikutsut toimivat samalla tavalla. Tämä mahdollistaa luokan sisäisen koodin uudelleenkirjoituksen, jos rajapinta (parametrit, paluuarvot ja metodikutsut) pidetään samana. Kapselointi motivoi ohjelmoijat sijoittamaan samaan kokonaisuuteen liittyvän datan yhteen luokkaan, mikä lisää koodin ymmärrettävyyttä ja ylläpidettävyyttä. Koska selkeärajaisten luokkien kapselointi vähentää luokkien välistä datan siirtoa, minimoi se samalla koheesiota.

Olioiden kapselointia voidaan edistää näkyvyysmääreillä, jotka piilottavat olioiden dataa, jolloin olion jäsenmuuttujiin ei pääse ulkopuolelta käsiksi, mikä vähentää niiden väärinkäyttöä. Tällaista abstraktiota syntyy, jos luokka ei salli pääsyä sen sisäisiin tietoihin ilman, että jotain luokan metodia kutsutaan. Jotkin kielet (esimerkiksi Java) mahdollistavat luokkien pääsyrajoitusten eli näkyvyysmääreiden muokkaamisen, jolloin luokan sisäisiä tietoja voidaan merkitä `private` avainsanalla, ja luokan ulkopuoliseen käyttöön tarkoitetut metodit voidaan merkitä avainsanalla `public`. Myös näiden kahden vaihtoehdon välillä on avainsana `protected`, joka mahdollistaa metodin tai jäsenmuuttujan periytymisen luokan alaluokkiin, pitäen ne kuitenkin muiden luokkien olioilta piilossa. Muissa kielissä (kuten Pythonissa) abstraktiota helpottavien näkyvyysmääreiden suoraa vastinetta ei ole, vaan ohjelmoija toimii yleisesti hyväksyttyjen tapojen mukaan (esimerkiksi yksityisillä metodeilla voi olla alaviivalla alkavia nimiä).

Abstraktiot voidaan luokitella: "is-a" ja "has-a" -abstraktioihin. Asiaa pilkkoessamme käytämme "has-a"-abstraktiota, kun pohdimme, mistä kokonaisuus koostuu esim: Pullo koostuu itse pullosta, etiketistä, korkista ja sisällöstä. Erikoistuminen taas kuvaa "is-a" -abstraktiota. Tällöin mietimme, mitkä luokat kuuluvat laajempiin luokkiin. Tämä muodostaa perustan luokkien väliselle periytymielle esim: lasipullo on pullo, ja pullo on pakkaus.

Hierarkia olioiden tietojäsenten välillä on tärkeä osa olio-ohjelmointia. Toisin sanoen se on abstraktion järjestämistä tai järjestelyä. Hierarkia mahdollistaa systeemin kokoamisen pienemmistä yhdistetyistä kokonaisuuksista, jotka voivat koostua vielä pienemmistä kokonaisuuksista, kunnes pienin mahdollinen systeemin taso on saavutettu. Hierarkian perustuu "Hajota ja hallitse" -periaatteeseen, jossa ongelmaa pilkotaan pienempiin helposti ratkaistavampiin osiin, joista lopullinen ratkaisu kootaan.

Olio-ohjelmoinnissa pyritään olioiden hyvään koheesioon. Olioiden tulee vastata jotakin yksiselitteistä ja selkeärajaista käsitettä. Olion tietojäsenet liittyvät kiinteästi toisiinsa. Esimerkiksi opintorekisteritietojärjestelmässä ei samaan olioon tallenneta opiskelijan ja hänen käymiensä kurssien tietoja, vaan opiskelijaolio sisältää pelkästään opiskelijan tiedot ja viittaukset opintosuoritusolioihin.

Olioiden välisten riippuvuuksien hallinta on tärkeää laajoissa oliojärjestelmissä. Oliolla on riippuvuus kaikkiin niihin olioihin, joille se lähettää viestejä. Olioiden tulisi kommunikoida vain muutamien läheisesti olioon liittyvien olioiden kanssa. On vältettävä tilannetta, jossa järjestelmän kaikki oliot joutuvat olemaan tietoisia suuresta määrästä muita olioita eri puolilta järjestelmää.

Olioita pyritään ohjelmoimaan niiden rajapintoja vastaan. Rajapinta kuvaa olion tarjoamat palvelut, eli mitä olio tekee. Olion toteutuksen yksityiskohdat, eli miten olio toimii, pyritään piilottamaan muilta olioilta. Käytännössä olion rajapinta koostuu sen julkisista metodeista ja jäsenmuuttujista. Oliolla voi olla myös suojattuja metodeja ja jäsenmuuttujia, jotka eivät ole käytettävissä olion ulkopuolelta. Usein jäsenmuuttujien käsittely olion ulkopuolelta estetään ja olion tilaa voidaan käsitellä vain sen jäsenfunktioiden avulla.

Rajapintaluokat (*interface*) määrittelevät pelkästään rajapinnan ilman toteutusta. Rajapintaluokkien käyttö mahdollistaa tietyn toiminnon toteutuksen varioimisen ohjelmassa. Konkreettiset luokat, jotka perivät rajapintaluokan, voivat toteuttaa rajapintaluokan määrittelemän rajapinnan haluamallaan tavalla.

SOLID on yksi olio-ohjelmoinnin pääperiaatteista. Periaatteet esitteli ensin Robert J. Martin, mutta SOLID lyhennettä käytti ensin Michael Feathers.

SOLID koostuu seuraavista säännöistä:

* Yhden vastuun periaate (Single Responsibility Principle): Luokalla tulisi olla vain yksi tehtävä, ja siksi vain yksi syy muuttua.
* Avoin-suljettu periaate (Open-Closed Principle): Luokkien kuuluu olla avoimia laajennukselle ja suljettuja muokkaukselle.
* Liskovin korvausperiaate (Liskov Substitution Principle): Liskovin periaatteen mukaan kantaluokan olio pitäisi aina pystyä korvaamaan alaluokan oliolla.
* Rajapinnan erotteluperiaate (Interface Segregation Principle): Rajapinnat pitää olla eroteltu eri tarkoituksiin, yleisiä rajapintoja pitää välttää.
* Riippuvuuden käänteisyyden periaate (Depency Inversion Priciple): Luokkien tulisi riippua rajapinnoista ja abstrakteista luokista, konkreettisten luokkien ja funktioiden sijaan.

Polymorfismi tarkoittaa olioiden kykyä ottaa monta muotoa. Sen nimi tulee kreikan “poly”, joka tarkoittaa lukuista ja “morphs” tarkoittaa muotoa. Esimerkiksi ihminen voi olla jonkun lapsi, puoliso ja työntekijä samaan aikaan ja käyttäytyä eri tavalla eri tilanteessa. Samalla tavalla kantaluokan lapsiluokat voivat määrittää oman käyttäytymisensä ja jakaa osan kantaluokan samoista toimintatavoista.

Polymorfismi tapahtuu, kun luokka perii ominaisuuksia toiselta luokalta. Yleisin tapaus on se, kun kantaluokan viittausta käytetään viittaamaan lapsiluokkaobjektiin. Voidaan selvittää, onko objekti polymorfinen, suorittamalla “is-a” tai “instanceof” testejä. Javassa kaikki oliot ovat polymorfisia.

Polymorfismin ominaisuudet ovat metodien toiminnallisuuden eri käyttäytyminen eri skenaarioissa, metodien käyttäytymisen riippuvuus eri annetuista tiedoista, jäsenien tai metodien sama nimi erityyppisissä luokassa, implisiittisen tyyppimuunnoksen tukeminen.

Javassa on kaksi tyyppiä polymorfismia. Staattisessa polymorfismissa luokassa on useita metodeja, joilla on sama nimi samassa luokassa, mutta jokaisella on eri määrä parametreja tai eri tietotyyppien parametreja. Sellaisia funktioita kutsutaan ylikuormituksiksi (method overloading). Metodikutsun käsittelee kääntäjä. Toinen polymorfismin tyyppi on dynaaminen. Se esiintyy, kun lapsiluokalla on oma määritelmänsä yhdelle kantaluokan jäsenmetodeista. Tätä kutsutaan metodin ohitukseksi (method overriding). Näiden kahden polymorfismin välillä ero on se, että staattinen polymorfismi kerää tiedot metodin kutsumiseksi käännöshetkellä, kun taas dynaaminen polymorfismi kerää tiedot metodin kutsua varten ajon aikana.

Polymorfismi eroaa periytymisestä. Periytymisessä ilman polymorfiaa lapsiluokka perii samat kantaluokan attribuutit ja metodit ilman muutoksia niiden toimivuuteen. Polymorfismissa lapsiluokka perii attribuutit ja metodit, mutta tarjoaa näille menetelmille oman toteutuksen.

Periytymisessä aliluokan vastuulla on jäsenmuuttujien ja muiden tietorakenteiden alustaminen ja kantaluokan vastuulla on pitää huoli, että aliluokan olion kantaluokkaosa alustetaan oikein. Aliluokka tarjoaa kaikki samat palvelut mitä kantaluokkakin ja mahdollisesti vielä jotain omaa. Aliluokan olio on tyypiltään myös kantaluokan olio.

Toinen käytetty olio-ohjelmoinnin periaatteista on Craig Larmanin kirjassaan Applying UML and Patterns kuvailema GRASP, eli General Responsibility Assignment Software Patterns. Se on kahdeksan periaatteen kuvailema suhde suunnittelun ja vastuunjakamisen välillä. GRASP periaatteet ovat ohjaaja, luoja, informaatioasiantuntija, alhainen yhteenliittäminen, korkea koheesio, polymorfismi, suojatut variaatiot ja täydellinen fabrikaatio. GRASP periaatteita voidaan käyttää SOLID periaatteiden tapaan hahmottamaan ja kuvailemaan yleisiä olio-ohjelmoinnin ongelmia sekä niiden ratkaisuja. Olio-ohjelmoinnin periaatteet eivät ole fyysisiä työkaluja, vaan ajatusmalleja, joiden avulla voidaan kehittää parempaa sekä selkeämpää koodia. Yhdessä kummatkin periaatteet määrittelevät keskeisiä olio-ohjelmoinnin konsepteja sekä kehitysmalleja.

## Menetelmiä

Olio-ohjelmointi on vaikuttanut suuresti ohjelmistotuotannon menetelmiin ohjelmiston elinkaaren kaikissa eri vaiheissa.

Olioanalyysi on keskeinen osa olio-ohjelmiston määrittelyä ja suunnittelua. Olioanalyysissa selvitetään ongelma-alueen (problem domain) käsitteet (concepts) ja niiden väliset rakenteelliset ja toiminnalliset suhteet. Olioanalyysin tuloksena on käsitemalli (concept model), josta toteutuksen luokkamäärittelyt voidaan suoraviivaisesti johtaa.

Olioanalyysia varten on kehitetty useita mallinnuskieliä. Mallinnuskielet poikkeavat monella tavalla tavallisista oliokielistä: Mallinnuskielet eivät ole suoritettavia, vaan ne kuvaavat järjestelmän rakennetta korkeammalla abstraktiotasolla ilman yksityiskohtia. Mallinnuskieliä käytetään pääasiassa graafisella notaatiolla, mikä mahdollistaa suurten kokonaisuuksien havainnollistamisen diagrammien avulla. Mallinnuskielten rakenne on kuitenkin tarkoin määritelty, jotta mallit eivät olisi tulkinnanvaraisia. Object Management Groupin (OMG) Unified Modeling Language (UML) on saavuttanut hallitsevan aseman yleiskäyttöisten mallinnuskielien joukossa. UML on standardi graafinen mallinnuskieli, joka tarjoaa useita erilaisia kaavioita, joista tunnetuimpia ovat luokkakaavio, sekvenssikaavio, käyttötapauskaavio sekä tilakaavio.

Luokkakaavio sisältää luokan, attribuutit (luokan sisältämä tieto), metodit (luokan toiminnallisuus) sekä luokkien väliset yhteydet. Alla esimerkki luokkakaaviossa kuvatusta Nappula-luokasta, jolla on muuttujia dataa varten sekä funktioita. Esimerkin taulukossa viisi ylintä ovat yksityisiä attribuutteja ja kolme alinta ovat julkisia metodeja.

|  |
| --- |
| Nappula |
| - xkoko |
| - ykoko |
| - xsijainti |
| - ysijainti |
| - teksti |
| + piirrä() |
| + paina() |
| + rekisteröi\_takaisinkutsu() |

Suunnittelumallit (design patterns) syntyivät alun perin rakennusarkkitehtuurin piirissä, mutta niiden idea otettiin käyttöön olio-ohjelmoinnissa 1990-luvun alussa. Suunnittelumalli on toistettavissa oleva ratkaisu johonkin suunnitteluongelmaan tietyssä asiayhteydessä. Suunnittelumallin kuvaus sisältää ainakin nimen, kuvauksen olosuhteista joissa sitä voi soveltaa, ratkaisun kuvauksen ja ratkaisun seuraukset. Yleisesti tunnettujen nimettyjen ratkaisumallien käyttö tehostaa viestintää ohjelmistosuunnittelijoiden välillä ja parantaa varsinaisten toteutusten selkeyttä ja rakennetta.

Suunnittelumallit voidaan laajasti jakaa kolmeen osaan: luontimalleihin, rakennemalleihin ja käyttäytymismalleihin. Luontimallien avulla pysytään luomaan olioita hallitusti tilanteen vaatimalla tavalla. Näin pystytään vähentämään järjestelmän monimutkaisuutta ja epävakautta ja samalla parannetaan sen joustavuutta ja koodin uudelleenkäytettävyyttä. Yksi suosittu luontimalli on singleton (ainokainen), jolla varmistetaan, että luokasta tehdään vain yksi instanssi. Tämä instanssi tulee myös olla saavutettavissa globaalisti, jotta muut järjestelmän osat pääsevät sen sisältämään tietoon käsiksi. Singlettomassa luokkamuuttuja ja luokkafunktio on laitettu yhteen. Tällöin voidaan olla varmoja, ettei tehdä kuin yksi olio tätä kyseistä tyyppiä. Tämä on yksinkertainen, mutta tehokas malli, jonka avulla tietoa saadaan jaettua ilman tarvetta luoda uutta oliota jokaiselle sitä tarvitsevalle komponentille.

Rakennemallit ovat hyödyllisiä muodostaessa suuria, joustavia ja tehokkaita rakenteita olioista, jotka ovat muuten olisivat erillään. Näillä rakenteilla pystytään siis esimerkiksi määrittelemään komponenttien välisiä yhteyksiä ja ne ovat erityisen hyödyllisiä suurissa järjestelmissä. Rakennemalleista esimerkki voisi olla decorator (kuorruttaja), jonka avulla pystyy lisäämään toimintoja olioon muuttamatta sen pohjalla olevaa rakennetta. Uusia "kerroksia" lisätessä kuitenkin kannattaa olla varovainen, että niitä tule lisättyä liian monta, joka johtaisi turhaan monimutkaisuuteen.

Käyttäytymismallit ovat vastuussa tehokkaasta komponenttien välisestä kommunikaatiosta. Nämä mallit huolehtivat olioiden välisestä vuorovaikutuksesta ja vastuiden määrittelystä. Näiden mallien tavoite on tehdä näistä prosesseista mahdollisimman yksinkertaisia ja helppoja ymmärtää. Yksi esimerkki käyttäytymismalleista on observer (tarkkailija), jota käytetään usein, kun jokin olio on vuorovaikutuksessa monen muun olion kanssa. Malli toimii siten, että oliot, jotka tarkkailevat yhtä tiettyä oliota saavat heti tietää, jos tarkkailtu olio muuttuu tai vaihtaa tilaa. Käyttäytymismalli kuvaa myös ohjelmiston luokat. Malli voi olla luokkiin perustuva, olioihin perustuva tai toiminnallisuuden kapselointi olioon perustuva. Olioihin perustuva yksi käyttäytymismalli on Chain of Responsibility (vastuuketju), joka perustuu siihen, että toiminnot delegoidaan olioille. Tiedonsiirto, joka tapahtuu olioiden välillä perustuu pyynnön käsittelevien olioiden muodostamasta ketjusta, jossa pyyntö käsitellään siinä olevasta oliossa, joka on kyvykäs toteuttamaan pyynnön.

Olioteknologioiden käyttö ohjelmiston suunnittelussa ja toteutuksessa ei ohjaa minkään tietyn prosessimallin käyttöön tai muuta ohjelmiston laadunvarmennuksen perusperiaatteita. Olioteknologian asiantuntijat ovat kuitenkin osallistuneet aktiivisesti keskusteluun ohjelmistoprosesseista. Ketterät menetelmät, käyttötapausmallinnus ja testivetoinen kehitys syntyivät pienessä Smalltalk-kehittäjien yhteisössä, josta ne ovat levinneet yleisempään käyttöön vuosituhannen vaihteen jälkeen.

## Polymorfismi - monimuotoisuus

Alatyypitys (subtyping) on yksi monimuotoisuuden ilmentymä. Alatyypityksessä kutsuttu koodi voi olla riippumaton siitä, missä tuetussa hierarkiassa se toimii, esimerkiksi kantaluokka tai jokin kantaluokan lapsiluokka. Samaan aikaan, esimerkiksi saman niminen metodi eri luokissa voi toimia eri tavalla, kun on kyse periytymisestä.

Esimerkiksi luokat, jotka ovat tyyppiä Ympyrä ja Neliö, ovat periytyneet kantaluokasta Muoto. Piirrä-metodi jokaisella luokalla, jotka ovat periytyneet Muoto-luokasta, implementoivat metodin itselleen vaatimallaan tavalla, jotta vaadittu muoto piirtyy. Samalla koodin kutsuminen ei muutu, vaikka käsiteltäisiinkin monia eri Muoto-luokan lapsiluokkia, koska jokaisella lapsiluokalla on Piirrä-metodi ja sitä voidaan kutsua yleisesti Muoto-luokan kautta.

## Kapselointi

Tiedon piilotus eli kapselointi tarkoittaa, ettei olion tilaa pääse muuttamaan muuten kuin olion metodien välityksellä. Olio kapseloi sisäänsä käytöksensä, tilansa ja identiteetinsä. Olion käytös kuvataan sen metodeissa. Metodi suoritetaan, kun olio saa viestin toiselta oliolta. Olio valitsee viestin perusteella metodin, jonka se suorittaa. Olion tilan muodostavat sen attribuutteihin sijoitetut arvot tiettynä ajanhetkenä. Identiteetti yksilöi olion: kahdella oliolla voi olla sama tila, mutta eri identiteetti; ts. ne ovat kaksi eri oliota. Identiteetti määräytyy automaattisesti oliota luodessa.

## Luokka- vs. Prototyyppipohjainen

Luokkapohjaisessa ohjelmoinnissa luokat on määritelty etukäteen ja oliot on luotu luokkiin pohjautuen. Jos kaksi oliota *omena* ja *appelsiini* ovat luotu luokasta *hedelmä*, ovat molemmat hedelmiä ja on taattu, että voit käsitellä niitä samalla tavalla; esim. Ohjelmoija voi olettaa kummallakin olevan samat ominaisuudet, kuten *väri*, *sokeripitoisuus* tai *on\_raaka*.

Prototyyppipohjaisessa kielessä oliot ovat itsenäisiä kokonaisuuksia. Luokkia ei ole. Olion prototyyppi on vain toinen olio, johon olio on linkitetty. Jokaisella oliolla on prototyyppilinkki (vain yksi). Uusia olioita voi linkittää jo valmiina oleviin olioihin linkittämällä se tämän prototyypiksi. Voit kutsua kahta eri objektia, *omena* ja *appelsiini, Hedelmäksi*, jos olio *Hedelmä* on olemassa sekä molemmilla olioilla, *omenalla* ja *appelsiinilla,* on asetettu *Hedelmä* prototyypiksi. *Hedelmä* ei ole tässä luokkana vaan olion jakavana ekvivalenssiluokkana. Olion attribuutit ja metodit on delegoitu kaikille tämän prototyypin määrittämän ekvivalenssiluokan olioille. Olion omistamia atribuutteja ja metodeja ei siis voi jakaa muille ekvivalenssiluokan olioille; esim. Attribuutti *sokeri\_pitoisuus* voi puuttua oliosta *omena.* Prototyypin kautta voidaan toteuttaa vain yksi perintö.

## Agenttiohjelmointi

Agenttiohjelmointi (engl. Agent-oriented programming, AOP) on ohjelmointiparadigma, joka pohjautuu ohjelmistoagentteihin. Toisin kuin olio-ohjelmoinnissa, joka perustuu metodeja tarjoaviin olioihin, agenttiohjelmoinnissa ohjelmiston yksittäiset komponentit ovat “agenteiksi” kutsuttuja itsenäisiä tietokoneohjelmia. Nämä agentit toimivat itsenäisesti ja kommunikoivat keskenään viestien avulla, jotta voidaan saavuttaa niille annettuja tavoitteita. Agentit voivat myös suorittaa toimintoja ympäristössään ja havainnoida ympäristön tilaa. Agenttiohjelmointia käytetään usein monimutkaisten järjestelmien kehittämiseen, joissa on paljon vuorovaikutusta komponenttien välillä. Agenttiohjelmoinnista on tullut myös tärkeä osa tekoälytutkimusta ja sitä käytetään muun muassa robotiikkaan ja puheentunnistukseen.

Agenttiohjelmoinnin historia ulottuu vuoteen 1990, kun Yoav Shoham esitteli käsitteen tekoälytutkimuksessaan. Hänen luomansa agentit olivat erityisiä, koska niillä on vain yksi metodi yhdellä parametrillä. Agenttiohjelmoinnin käsite alkoi vakiintua 1990-luvun lopulla, kun useat tutkijat alkoivat kiinnostua siitä. Esimerkiksi vuonna 1998 James Odell julkaisi kirjan ”Object-Oriented Analysis, Design and Implemention”, jossa hän puhui myös agenttiohjelmoinnista. Vuonna 2000 agenttiohjelmoinnista tuli virallisesti IEEE:n (Institute of Electrical and Electronics Engineers) standardi.

## Avoin rekursio

Kielissä, jotka tukevat avointa rekursiota, voivat luokan metodit kutsua toisia metodeja, jotka ovat samassa luokassa, tai itseään. Metodeja kutsutaan yleisesti käyttäen erikoismuuttujia tai avainsanoja nimeltään "this" tai "self".

## Konstruktori

Konstruktoria voidaan kutsua myös muodostimeksi tai rakentajaksi. Luokkapohjaisessa olio-ohjelmoinnissa muodostin on funktio, jota kutsutaan luomaan olio. Se vastaa uuden olion alustamisesta ja asettaa jäsenmuuttujat alkuarvoihin. Sillä ei ole eksplisiittistä palautustyyppiä eikä se ole implisiittisesti peritty. Muodostaja on usein saman niminen kuin luokka. Muuttumaton olio täytyy alustaa muodostajassa. Useimmissa ohjelmointikielissä (Java, Python, C++ jne.) luokalla voi olla useampi kuin yksi muodostaja, joilla on erilaiset parametrit.

Olio-ohjelmoinnissa muodostaja tyyppejä on erilaisia. Parametrilliset muodostajat (parameterized constructor) voivat ottaa vähintään yhden argumentin ja ne mahdollistavat tietojen asettamisen, kun luokkaa luodaan. Oletusmuodostaja (default constructor) on parametriton muodostaja ja sen toiminta on kielestä riippuvainen. Javassa oletusmuodostajan luo kääntäjä automaattisesti, jos luokalle ei ole sitä määritetty. Tyyppien arvot ovat silloin oletusarvoissa eli kokonaislukutyypit jätetään arvoon 0, liukulukutyypit arvoon 0,0 ja boolean-tyyppi arvoon false ja viitetyypit ovat null.

Kopiontimuodostajassa (copy constructor) on yksi muodollinen parametri, joka on luokan tyyppi ja parametri voi olla viittaus olioon. Tätä käytetään, kun halutaan luoda kopio saman luokan olemassa olevasta oliosta. Muunnoskonstruktori (conversion constructor) tarjoaa keinon luoda implisiittisesti yhteen luokkaan kuuluvan olion erityyppisen olion perusteella. Muunnoskonstruktori mahdollistaa tietotyypin automaattisen muuntamisen toiseksi oliota luodessa. C++:ssa siirtomuodostajat (move constructor) ottavat Rvalue-viittauksen luokan olioon. Niitä käytetään resurssien omistajuuden siirtämiseen.

## Roolisuuntautunut ohjelmointi

Roolipohjainen ohjelmointi on ohjelmoinnin muoto, jossa asioita ilmoitetaan termien avulla, jotka yrittävät ilmoittaa ihmisen näkökulmasta, tämä tekee koodin lukemisesta sekä

ymmärtämisestä helpompaa kuin tavallisen koodin.

Pääajatus rooli pohjaisessa ohjelmoinnissa on se, että ihmiset ajattelevat koodin toimintaa roolien läpi. Esimerkkinä rooli pohjaiselle ohjelmille käytetään ihmistä jolla on useita eri rooleja kuten työ rooli tai koti rooli. Tämän henkilön vuorovaikutukset riippuvat siis pitkälti hänelle annetuista rooleista ja niiden ominaisuuksista. Ominaisuudet jaetaan usein delegoimalla tietyt tehtävät tietylle oliolle.

Roolipohjaisen ohjelmoinnin edut eivät myöskään rajoitu vain koodin ymmärrettävyyden paranemiseen. Roolipohjainen ohjelmointi myös helpottaa ohjelmiston testaamista sekä ylläpitoa. Kun ohjelmisto on rakennettu roolien ja niiden ominaisuuksien ympärille tekee se toimintojen testaamisesta helpompaa, sillä jokainen rooli ja sen vastuut on määritelty tarkasti.

Jolloin mahdollisten virheiden löytäminen on helpompaa

Vanhoissa ohjelmointi oppaissa sekä muissa opetusmateriaaleissa rooli pohjaista ohjelmointia on käsitelty huomattavan vähän. Se on kuitenkin hyödyllinen osa olio ohjelmointia ja sen merkitys on lisääntynyt uusien ohjelmistojen kehityksessä. Tämän tyylisessä ohjelmoinnissa roolit pyrkivät helpottamaan kontekstin ymmärtämistä. Roolilla voidaan myös tarkoittaa tiettyä joukkoa kuten ohjelmiston palveluita, jotka esimerkiksi mahdollistavat paremman paremman palvelimen suorituskyvyn tietyistä toiminnoista verkossa.

Tulevaisuudessa roolipohjaisen ohjelmoinnin merkitys ja käyttö tulee todennäköisesti kasvamaan, kun kehitetään yhä monimutkaisempia ohjelmistoja, joissa on useita toimintoja ja rooleja, jotka tarvitsevat erillistä huomiota ja käsittelyä.

(Role-oriented programming)

## Sovellusalueita

Olio-ohjelmoinnin ensimmäisiä käyttökohteita olivat diskreetit tapahtumasimulaatiot, joissa mallinnettiin esimerkiksi puhelinjärjestelmien tai logististen järjestelmien toimintaa.

Olio-ohjelmointi soveltuu erityisen hyvin graafisten käyttöliittymien toteuttamiseen. Käyttöliittymäkirjastot, kuten Swing, SWT tai MFC sisältävät luokkahierarkian, joissa käyttöliittymän komponenttien yhteisiä ominaisuuksia hallitaan perinnän avulla.

Olio-ohjelmointi on hallitseva paradigma myös tietojärjestelmien suunnittelussa. Reaalimaailman käsitteet mallinnetaan olioanalyysissä ja käsitteitä vastaavat luokat toteutetaan ohjelmointikielellä. Yleinen ongelma tietojärjestelmissä on olioiden avulla esitetyn mallin tallentaminen relaatiotietokantaan, sillä relaatiomalli voi esittää käsitteiden välillä monesta moneen suhteita, mutta ei toisaalta pysty esittämään perintäsuhteita.

Suosittu olio-ohjelmointikieli on C++. Se on yleiskäyttöinen ohjelmointikieli, joka laajentaa C-kieltä lisäämällä tuen olio-ohjelmointiin. C++:n avulla kehittäjät voivat toteuttaa objekteja, periytymistä, moninkertaisuutta ja muita olio-ohjelmointikonsepteja. C++:n ominaisuudet tekevät siitä tehokkaan ja joustavan kielen, jota käytetään laajalti esimerkiksi pelien kehittämisessä, grafiikkasovelluksissa ja sulautetuissa järjestelmissä. Olio-ohjelmointi ei rajoitu C++:aan, vaan muita suosittuja olio-ohjelmointikieliä ovat C#, Python ja Ruby. Näiden kielten avulla kehittäjät voivat hyödyntää olio-ohjelmoinnin etuja, kuten koodin uudelleenkäyttöä, kapselointia ja helpompaa ohjelman ylläpitoa. Olio-ohjelmointia käytetään laajasti erilaisissa sovelluksissa, kuten web-kehityksessä, mobiilisovelluskehityksessä, tietokannassa ja tekoälyssä. Sen avulla voidaan luoda modulaarisia ja laajennettavia ohjelmistoja, jotka on helpompi ymmärtää, ylläpitää ja laajentaa.

Olio-ohjelmoinnin periaatteiden ymmärtäminen ja sen soveltaminen ohjelmointiin on tärkeää nykyajan ohjelmistokehityksessä. Se antaa kehittäjille mahdollisuuden työskennellä tehokkaasti ja auttaa rakentamaan laadukkaita ja joustavia ohjelmistoja.

Hajautetuissa oliosovelluksissa oliot on sijoitettu hajalleen eri palvelinten välille. Olioiden välinen viestintä hoidetaan sovitun protokollan, esimerkiksi SOAPin, CORBA tai RMI:n avulla. Olion luominen ja purkaminen tapahtuvat näennäisesti oliota kutsuvalla koneella, mutta itse olion suorittama proseduuri voidaan ajaa jollakin toisella tietoverkossa sijaitsevalla palvelimella.

Oliopohjaisessa tiedontallennuksessa olioajattelua sovelletaan tiedon tallentamiseen siten, että kiinteiden blokkien tai tiedostojen sijaan tai ohella viitataan olioihin, jotka voivat esimerkiksi yhdistellä tietoja useammasta paikasta ja jakaa sitä helposti keskenään. Esimerkiksi Windowsiin suunniteltiin 1990-luvun puolivälissä oliopohjaista tiedostojärjestelmää, mutta ajatus toteutui vain osin: esimerkiksi Ohjauspaneelin asetussovelluksiin viitataan käyttöjärjestelmän sisäisesti olioina, ei kiinteinä tiedostoina.

#### Olio-ohjelmoinnin käyttö verkkoprotokollassa

Viestit, jotka liikkuvat palveluja pyytävän tietokoneen ja kyseistä palvelua tarjoavan palvelimen välillä, voidaan suunnitella luokkaobjekteiksi määritellyiksi objektijonoiksi. Kyseiset luokkaobjektit ovat viestivien osapuolten (eli tietokoneen ja palvelimen) tiedossa jo ennalta. Objekti voisi koostua esimerkiksi pituuskentästä, luokan tunnisteen sisältävästä kentästä ja arvokentästä. Palvelimen pitää ohjata vastaanotetut viestit oliolle, joka tunnistaa viestissä lähetetyn käskyn ja pystyy tarjoamaan pyydetyn palvelun. Palvelua käyttävän asiakastietokoneen ja sitä tarjoavan palvelimen välistä yhteyttä mallinnetaan usein olio-orientoituneena rakenteena. IBM:n Distributed Data Management Architecture (DDM) soveltaa tätä tapaa.

#### Olio-ohjelmoinnin käyttö pelien kehittämisessä

Videopelit voivat koostua muutamista tuhansista koodiriveistä miljooniin koodiriveihin. Sen vuoksi on tärkeä kirjoittaa koodia, joka on helposti muokattavissa ja ylläpidettävissä. Ohjelmointi tyyleistä olio-ohjelmointi on yksi mahdollinen tapa, jolla saadaan luotua ylläpidettävää koodia, joka on mukautuvaa, ymmärrettävää ja laajennettavissa. Sen avulla voidaan luoda uudelleen käytettävää koodia noudattamalla DRY (Don’t Repeat Yourself) -menetelmää, eli suomennettuna, älä toista itseäsi menetelmää, joka tarkoittaa, että jokin tietty toiminnallisuus kirjoitetaan kerran ja tätä käytetään uudelleen, kopioimisen sijasta. Tämä tapa sopii hyvin pelien kehittämiseen, koska peleissä on asioita, joita halutaan tehdä monesti uudelleen. Olio-ohjelmointi tarjoaa tiettyjä erityisominaisuuksia, jotka voidaan nähdä etuina pelien kehittämisessä.

* Koheesio (cohesion),

* Yhdistäminen/kytkeytymien (coupling),
* Kapselointi (encapsulation),
* Abstraktio (abstraction),
* Periytyminen (inheritance)

Pelin kehityksen kannalta koheesiota voidaan käyttää tilanteessa, jossa haluamme liikuutta esimerkiksi avaruusalusta. Tällöin meillä voi olla luokka nimeltä liike, joka hoitaa liikkumisen ja sitä voidaan käyttää uudestaan. Kytkeytymien tulee huomioida peliä tehdessä esimerkiksi siten, että mitä tapahtuu tilanteessa, jossa avaruusalus törmää asteroidiin, tuhoutuuko se vai ei? Abstraktiota voidaan soveltaa useampien olioiden liikutteluun pelissä. Tietty toiminnallisuus voidaan abstraktoida abstraktiksi luokaksi. Esimerkiksi avaruusalus ja asteroidi tarvitsevat samoja tietoja liikkumiseen, joita ovat esimerkiksi, nopeus ja sijainti. Objektin liikkuminen voidaan periyttää abstraktista luokasta avaruusalukselle, jolloin sitä ei tarvita avaruusalus luokassa.

Esimerkkejä peleistä, jotka ovat tehty Javalla, joka on olio-ohjelmointi kieli:

* Wakfu
* Worms: A Space Oddity
* Sainst Row 2 (Mobile)
* SimCity
* Spiral Knights
* RuneScape
* Minecraft

## Ongelmia

Olio-ohjelmointi ei eduistaan huolimatta ole täysin ongelmatonta. Siinä missä proseduraalisessa ohjelmassa yhdessä kohtaa esiintynyt virhe saattoi vaikuttaa vain paikallisesti, olio-ohjelmoinnissa virheet monistuvat välittömästi kaikkiin oliota käyttäviin tahoihin. Olio-ohjelmoinnissa hyvän suunnittelun ja automatisoidun yksikkötestauksen merkitys korostuu. Väärin käytettynä olioilla voi myös olla suorituskykyvaikutuksia. Koska jokainen olio rakennetaan aina kokonaisuudessaan tietokoneohjelman muistiin, suurten oliomäärien käsittely voi viedä huomattavasti muistia.

Olio-ohjelmoinnin perusfilosofian (eli ohjelmointiparadigman) opettelu vie myös usein aikaa. Perinteisestä proseduraalisesta ohjelmoinnista olio-ohjelmointiin siirtyminen on joskus vaikeaa jopa kokeneille ohjelmistosuunnittelijoille. Nykyisin olio-ohjelmointia opetetaan useilla eri koulutustasoilla ja sen peruskäsitteet hallitaan yleisesti ottaen paremmin kuin ennen. Tästä huolimatta moni ohjelma suunnitellaan näennäisesti olioilla, mutta käytännössä ne noudattavat aikaisempaa ohjelmointityyliä, johon tekijä on tottunut. Olio-ohjelmointi ei siis tee kenestäkään parempaa ohjelmoijaa eikä automaattisesti anna mitään etuja suhteessa perinteiseen ohjelmointiin, ellei olio-ohjelmoinnin etuja osata oikealla tavalla hyödyntää.

Luokkien periyttämisen heikkoutena on eri luokkien käytännön toteutuksen sitominen toisiinsa, mikä saattaa aiheuttaa ongelmia siinä vaiheessa kun ohjelmistosta tehdään uusia versioita. Näiden ongelmien ennalta ehkäisemiseksi on tehty suunnittelumalleja, jotka perustuvat hyväksi havaittuihin ratkaisuihin.

Luca Cardelli on väittänyt, että olio-ohjelmoitu koodi on "luonnostaan vähemmän tehokas" kuin proseduraalinen koodi, että olio-ohjelmoidun koodin kääntäminen voi kestää kauemmin ja että olio-ohjelmointikielillä on "erittäin huonot modulaarisuusominaisuudet luokan laajennuksen ja muokkauksen suhteen" ja että ne ovat yleensä erittäin monimutkaisia. Jälkimmäisen seikan toistaa Joe Armstrong, Erlangin pääkeksijä, jota lainataan sanomalla:

> Olioperustaisten kielten ongelma on, että heillä on kaikki tämä implisiittinen ympäristö, jota he kuljettavat mukanaan. Halusit banaanin, mutta sait gorillan, joka piti banaania ja koko viidakkoa.
>
>

Potok et al.:n tutkimus ei ole osoittanut merkittävää eroa tuottavuudessa olio-ohjelmoinnin ja proseduraalisten menettelytapojen välillä.

Eräässä artikkelissa Lawrence Krubner väitti, että verrattuna muihin kieliin (LISP-murteet, funktionaaliset kielet jne.) olio-ohjelmointikielillä ei ole erityisiä vahvuuksia, ja niiden tarpeettomasta monimutkaisuudesta aiheutuu raskas taakka.

Paul Graham on ehdottanut, että olio-ohjelmoinnin suosio suurissa yrityksissä johtuu "suurista (ja usein muuttuvista) keskinkertaisten ohjelmoijien ryhmistä". Grahamin mukaan olio-ohjelmoinnin asettama kurinalaisuus estää yhtä ohjelmoijaa "tekemästä liikaa vahinkoa".

Clojure-ohjelmointikielen luoja Rich Hickey on kuvaillut oliojärjestelmiä liian yksinkertaisiksi todellisen maailman malleiksi. Hän korostaa olio-ohjelmoinnin kyvyttömyyttä mallintaa aikaa kunnolla, mikä on yhä ongelmallisempaa ohjelmistojärjestelmien samanaikaistuessa.

Unix-ohjelmoija ja avoimen lähdekoodin ohjelmistojen puolestapuhuja Eric S. Raymond on kritisoinut väitteitä, joiden mukaan olio-ohjelmointi esitetään "ainoana oikeana ratkaisuna", ja on kirjoittanut, että olio-ohjelmointikielet kannustavat yleensä paksukerroksisiin ohjelmiin, jotka tuhoavat läpinäkyvyyden. Raymondin mukaan tämä korostuu, kun olio-ohjelmointia verrataan Unixin ja C-ohjelmointikielen lähestymistapaan.

UTF-8 ja Go ohjelmisto projekteissa mukana ollut ohjelmoija Rob Pike, on kutsunut olio-ohjelmointia “tietojenkäsittelyn Roomalaisiksi numeroiksi” ja on sanonut, että olio-ohjelmoinnin kielet usein huomion datarakenteista ja algoritmeista tyyppeihin. Lisäksi hän mainitsee esimerkin Java professorista, jonka “käsittämätön” ratkaisu ongelmaan oli luoda kuusi uutta luokkaa sen sijaan että hän olisi yksinkertaisesti käyttänyt vain hakutaulua.

Perinnöllisyyden suhteen, Rob Martin toteaa, että koska kyseessä on tietokoneohjelmisto, sukulaisluokat eivät välttämättä jaa edustamiensa asioiden suhteita.

## Olion ja luokan ero

Aloittavalle olio-ohjelmoijalle luokan ja olion merkityksen ero voi olla vaikeaa hahmottaa. Yksikertaistettuna voidaan ajatella, että olio on konkreettinen asia ja luokka ei.

Eroa on usein helpompi ymmärtää erilaisten konkreettisten esimerkkien avulla.

Kun joillakin esineillä tai asioilla on monta yhteistä ominaisuutta, olisi hyödyllistä pystyä käsittelemään näitä asioita tai esineitä jotenkin kaikkia kerralla. Voidaan ajatella esimerkiksi autoa. Autoja on erilaisia, joilla on kaikilla tiettyjä samoja ominaisuuksia, kuten malli, valmistusvuosi ja hinta. Kun halutaan ajatella kaikkia autoja kerrallaan voidaan muodostaa Auto-luokka.

Toisena esimerkkina voidaan ajatella tilastoa, jossa yhdellä rivillä on monta eri tietoa, kuten sähkönkulutuksessa voisi olla aika, hinta ja kulutetun sähkön määrä. Tällöin voidaan muodostaa luokka joka sisältää jäsenmuuttuija nämä rivin sisältämät tiedot. Nyt kun tietoja halutaan siirtää paikasta toiseen voidaan ajatella pelkkiä rivejä, jotka sisältävät halutut tiedot. Tällöin tiedon siirtämisestä tulee yksinkertaisempaa, kun ei tietoa on vähemmän näkyvillä.

Luokka on ikään kuin kaava ja olio konkreettien tulos, joka saadaan syöttämällä tähän kaavaan tietyt parametrit.

Olio luodaan luokasta, joka toimii ”muottina” luotavalle oliolle. Luokat nimetään aina isolla alkukirjaimella ja oliot pienellä. Esimerkiksi ”henkilö” -olio luodaan ”Henkilö” -luokasta. Jäsenmuuttujat ovat hyvin tavallisesti määritelty yksityisiksi (private) jolloin ne ovat käytettävissä vain kyseisen luokan sisällä. Jotta yksityisiin muuttujiin päästään käsiksi, tähän tarvitaan jäsenfunktio (metodi). Alla esimerkki luokan, olion, jäsenmuuttujan ja jäsenfunktion käytöstä:

Luokka Henkilö

                            - nimi (jäsenmuuttuja)

                            + asetaNimi (jäsenfunktio)

                            + haeNimi (jäsenfunktio)

Luokasta Henkilö luotu henkilö olio:

                            Nimi = Kalle

Yksinkertainen Henkilö-luokka pitää sisällään jäsenmuuttujan: ”nimi” sekä tarvittavat jäsenfunktiot (metodit) esimerkiksi ”haeNimi” (noutaja = getter) ja ”asetaNimi” (asettaja = setter). Kun luokasta: Henkilö, luodaan olio: henkilö, uusi olio tarvitsee nimen, joka annetaan luokalle parametrina.  Koska luokan jäsenmuuttujat määritellään yksityisiksi, jolloin muuttujiin päästään käsiksi ainoastaan jäsenfunktioiden kautta. Tässä tapauksessa nimen hakeminen tapahtuu jäsenfunktiota haeNimi käyttämällä seuraavasti: henkilö.haeNimi() ja tämä palauttaa kyseisen olion jäsenmuuttujassa olevan arvon. Jos taas olemassa olevan olion nimeä halutaan muuttaa, se tapahtuu käyttämällä jäsenfunktiota henkilö.asetaNimi(Matti), jolloin olemassa olevan olion nimi muuttujaan asetetaan "Kalle" tilalle "Matti". Aseta nimi tarvitsee parametrinä uuden nimen muttei palauta mitään.

## Olio-ohjelmointia tukevia kieliä

Olio-pohjaiset ohjelmointikielet tarjoavat kehittäjille joukon työkaluja ja ominaisuuksia helpottaakseen olioiden luomista ja manipulointia. Vaikka on olemassa monia olio-ohjelmointia tukevia kieliä, Simula nähdään yleisesti ensimmäisenä kielenä, jossa on olennaiset piirteet olio-ohjelmoinnista. Toinen varhainen ohjelmointikieli on Smalltalk, jolla kehitettiin merkittävä osa olio-ohjelmoinnin teoriasta.tarvitaan parempi lähde

Olio-ohjelmointikielet voidaan jakaa "puhtaisiin" oliokieliin (joissa kaikki käsitellään olioina), olio-painotteisiin kieliin (jotka sisältävät joitain proseduraalisia elementtejä) tai alun perin proseduraalisiin kieliin, jotka ovat laajennettu olio-ohjelmointiominaisuuksilla. Joissakin kielissä on suurin osa olio-ominaisuuksista mutta eri muodossa (esim. Oberon). Toisissa kielissä on abstraktien tietotyyppien tuki, mitkä muistuttavat olio-ohjelmointia, mutta joilta puuttuu joitain ominaisuuksia (esim. JavaScript) .

On kuitenkin tärkeää huomata, että pelkän oliopohjaisen ohjelmointikielen käyttö ei takaa, että koodi noudattaa parhaita käytäntöjä olio-ohjelmoinnissa. Monet nykyaikaiset ohjelmointikielet on suunniteltu tukemaan olio-ohjelmointia, ja niissä on erilaisia ominaisuuksia, kuten luokkien määrittelyjä, perintämekanismeja, polymorfismia, jne. Olio-ohjelmoinnin käyttö mahdollistaa ohjelmistojen paremman järjestelmällisyyden, luettavuuden ja ylläpidettävyyden, mikä tekee siitä tärkeän kehitystyökalun modernissa ohjelmistokehityksessä.

Nykyään on olemassa monia oliopohjaisia ohjelmointikieliä, ja jokaisella näistä kielistä on oma ainutlaatuinen syntaksinsa ja joukko ominaisuuksia, jotka vaikuttavat ohjelman suorituskykyyn ja ohjelmoijan työnkulkuun. Jotkut näistä kielistä ovat suunniteltu erityisesti tiettyihin käyttötarkoituksiin, kuten verkkokehitykseen tai tieteelliseen laskentaan (esim. MATLAB), kun taas toiset ovat yleisempiä ja soveltuvat moneen eri tarkoitukseen.

Yleisimmät olio-ohjelmointia tukevat ohjelmointikielet ovat:

* Ada
* C++
* C#
* Common Lisp
* D
* Delphi
* Eiffel
* Gambas – Avoimen lähdekoodin kilpailija Visual Basicille
* MATLAB
* Object Pascal
* J#
* Java
* JavaScript
* Lazarus
* Neon
* Perl 5
* Pharo
* PHP (versio 5)
* Python
* REALbasic
* Ruby
* Scala
* Simula
* Smalltalk
* Visual Basic
* Visual Prolog

## Lähteet

* Koskimies, Kai: *Oliokirja*.  Helsinki:  Satku, 2000.  ISBN 951-762-720-3

### Viitteet

## Kirjallisuutta

* Sytykeraportti: *Oliot systeemityössä*.  Suomen Atk-Kustannus, 1998.  ISBN 951-762-165-5
* Meyer, Bertrand: *Object-Oriented Software Construction*.  Prentice-Hall, 1998.  ISBN 0-13-629155-4
* Sakkinen, Markku: *Inheritance and Other Main Principles of C++ and Other Object-oriented Languages*.  (Jyväskylä Studies in Computer Science, Economics and Statistics 20)  University of Jyväskylä, 1992.
* Smed, Jouni & Hakonen, Harri & Raita, Timo: *Sopimuspohjainen olio-ohjelmointi Java-kielellä*. Elektroninen kirja, 2007. ISBN 978-952-92-1776-2
* Coad, Peter & Nicola, Jill: *Object-Oriented Programming*.  Prentice Hall, 1993.  ISBN 0-13-032616-X
* Gamma, Erich & Helm, Richard & Jonson, Ralph & Vlissides, John: *Design Patterns. Olio-ohjelmointi. Suunnittelumallit*.  Edita, IT Press, 2001.  ISBN 951-826-428-7
* Koskimies, Kai: *Pieni oliokirja*, s. 1–281.  Espoo:  Suomen ATK-kustannus, 1998.  ISBN 951-762-503-0

## Aiheesta muualla

* Kuvia tai muita tiedostoja aiheesta Olio-ohjelmointi Wikimedia Commonsissa