wiki:Olioista
Last modified 7 years ago Last modified on 2012-06-01 21:43:13

Apuja ohjelmointiin » Olioista

Olio (engl. object) on luokan ilmentymä. Toisin sanoen yhdestä luokasta voidaan luoda useita olioita, ja nämä oliot ovat tyypiltään sen luokan ilmentymiä, joista ne on luotu. Luokat ovat tietotyyppejä samaan tapaan, kuin vaikkapa int tai double.

int luku;
Luokka olio;

Olioilla on ominaisuuksia (properties) ja metodeita (methods). Ominaisuuksilla tarkoitetaan arvoja kuten pelaajan terveys tai paikka pelimaailmassa. Metodit taas ovat aliohjelmia, kuten pelihahmon liikuttaminen. Kumpiinkin voidaan viitata olion nimen jälkeen kirjoitettavalla piste-operaattorilla.

olio.Leveys = 20;
olio.Ammu();

Olioiden ominaisuudet ja metodit on määritetty niiden luokassa. Toisin sanoen kahdella samaa luokkaa olevalla oliolla on aina samat ominaisuudet ja metodit. Ominaisuuksia ja metodeita kutsutaan yleisemmin luokan jäseniksi (members).

Olion luominen

Olion luomiseen käytetään erityistä new-avainsanaa, joka käyttää olion rakentajaa (constructor) sen luomiseen:

Timer kello = new Timer();

Suluissa voidaan tarvittaessa antaa rakentajalle parametreja. Rakentajia voi olla erilaisia, riippuen käyttötarkoituksesta. Seuraavassa esimerkissä luodaan neliö ja ympyrä, jotka kumpikin ovat fysiikkaolioita, mutta eri rakentajaa käyttäen:

PhysicsObject nelio = new PhysicsObject( 40.0, 40.0, Shape.Rectangle );

PhysicsObject ympyra = new PhysicsObject( 40.0, 40.0);
ympyra.Shape = Shape.Circle;

Olioon viittaaminen

Olioon viitataan aina sen nimellä. Jos halutaan käyttää jotain oliolle kuuluvaa, kuten ominaisuuksia, metodeita tai tapahtumia (näistä lisää alempana tällä sivulla), käytetään aina piste-operaattoria, eli kirjoitetaan piste olion ja ominaisuuden väliin.

Jos olioon viitataan sen itsensä sisältä, kuten esimerkiksi pelissä viitataan peliolioon itseensä, ei tarvita olion nimeä ja piste-operaattoria. Jos silti halutaan viitata olioon nimellä, voidaan käyttää varattua sanaa this.

Ominaisuudet

Ominaisuus (property) voi olla esimerkiksi paikka, väri tai vaikkapa kissalla hännän pituus.

kissa.X = 20.0;
kissa.HannanPituus = 7;

Ominaisuus voi olla myöskin olio:

Koira koira = new Koira();
kissa.vihollinen = koira;

Sama yhdelle riville kirjoitettuna:

kissa.vihollinen = new Koira();

Joillekin ominaisuuksille voi asettaa arvoja, toisia pelkästään lukea riippuen siitä, miten (olio-)luokan suunnittelija on tarkoittanut sen käytettäväksi. Jos ominaisuudelle, jonka arvoa ei voi asettaa, yrittää asettaa arvoa, antaa kääntäjä virheen:

Property or indexer 'luettava' cannot be assigned to -- it is read only

Metodit

Metodi on aliohjelma, joka on kirjoitettu olion sisälle. Samat säännöt parametrien ja paluuarvon kanssa pätevät.

int summa = laskuri.LaskeYhteen( a, b );
pallo.Hit( 2000 );
Controls.Listen( Keys.Space, ButtonPosition.DOWN, Ammu );

On myös olemassa ns. staattisia metodeita, joiden kutsumiseen ei tarvita oliota vaan niitä voidaan kutsua luokasta itsestään:

int satunnaisluku = RandomGen.NextInt( 1, 100 );
PhysicsObject kiinteaSuorakulmio = PhysicsObject.CreateStaticObject(40.0, 40.0);

Jäsenet

Luokan jäseniksi sanotaan sen ominaisuuksia ja metodeja.

Periytyminen

Monet luokat eivät itsessään sisällä kaikkia metodeja ja ominaisuuksia, vaan perivät nämä joltain toiselta luokalta. Esimerkiksi PhysicsObject-luokka on GameObjectin perillinen, mikä tarkoittaa, että siitä tehdyt oliot sisältävät PhysicsObjectin omien ominaisuuksien ja metodien lisäksi myös kaikki samat jäsenet kuin GameObject-oliotkin. Vastaavasti PlatformCharacter perii kaikki PhysicsObjectin (ja sitä kautta myös GameObjectin) metodit ja ominaisuudet.

C#-kielessä luokka voi periä vain yhden toisen luokan. Joissain ohjelmointikielissä, kuten C++:ssa, luokat voivat periä jäseniä useammilta luokilta. Tätä sanotaan moniperinnäksi, ja se jakaa mielipiteitä ohjelmointipiireissä: toistaalta moniperinnällä voidaan tehdä monipuolisempia luokkia, mutta toisaalta sen ylikäyttö aiheuttaa helposti vaikeasti löydettäviä ohjelmavirheitä.

Luokkaa, josta toinen luokka periytyy, sanotaan kantaluokaksi. Esimerkiksi GameObject on PhysicsObjectin kantaluokka. Vastaavasti PhysicsObject on GameObjectin perillinen.

Olioiden periytymisestä piirretään monesti luokkakaavioita. Luokkakaavio voi näyttää vaikkapa tältä:

Polymorfismi

Polymorfismiksi sanotaan sitä, kun peritty luokka esiintyy kantaluokkansa tyyppisenä. Esimerkki valoittaa asiaa:

GameObject peliolio = new PhysicsObject(20, 20);

Polymorfismia käytetään usein parametrien välityksessä aliohjelmalle, ettei jokaiselle peritylle luokalle tarvitse tehdä omaa aliohjelmaa.

void Aliohjelma1()
{
   PhysicsObject peliolio = new PhysicsObject(20, 20);
   Aliohjelma2( peliolio );
}

void Aliohjelma2( GameObject otus )
{
   // tehdään jotain pelioliolla otus
}

Tämä toimii, koska kaikki PhysicsObjectit ovat myös GameObjecteja. Toisin päin ei toimi, sillä läheskään kaikki GameObjectit eivät ole PhysicsObjecteja.

On huomattava, että vaikka peliolio on oikeasti tyyppiä PhysicsObject, Aliohjelma2 näkee sen GameObjectina, ja siten ei pääse käsiksi sen PhysicsObject-ominaisuuksiin, kuten Hit-metodiin tai Velocity-ominaisuuteen. Tähän on kuitenkin olemassa ratkaisu:

void Aliohjelma2( GameObject otus )
{
   PhysicsObject fysOtus = otus as PhysicsObject;
   if ( fysOtus != null )
   {
      physOtus.Hit( new Vector(200, 0) );
   }
}

Ylläolevassa esimerkissä muutetaan ensin GameObject-tyyppinen olio otus tyyppiin PhysicsObject ja tallennetaan muunnoksen tulos muuttujaan fysOtus. Jos muunnos ei onnistu (otus ei ole tyyppiä PhysicsObject), fysOtus saa arvon null. Tähän kannattaa varautua ehtolauseella, kuten yo. esimerkissä on tehty. Jos näin ei tehdä ja otus on muuta tyyppiä, seuraa NullPointerExcpetion-virhe.

Attachments