Virtuaalimetodi
Virtuaalimetodi tai virtuaalifunktio (engl. virtual method, engl. virtual function) on olio-ohjelmointikielien ominaisuus, jolla perintää käyttävä olio voi korvata yliluokassa olevan metodin toteutuksen toisella. Virtuaalimetodeja tukevia kieliä ovat esimerkiksi C++ ja Object Pascal.[1]
Virtuaaliosoitin (engl. virtual pointer) on funktio-osoittimen tapaus, jolla virtuaalimetodeihin viitataan. Virtuaaliosoittimet sijoitetaan ajonaikaisesti virtuaalimetoditaulukkoon (engl. virtual method table, engl. virtual call table).
Mikäli perityssä luokassa ei ole toteutusta virtuaalimetodille kutsut tehdään kantaluokan toteutukseen. Abstrakti pure virtual metodi, jolla ei ole toteutusta kantaluokassa on pakko toteuttaa perityssä luokassa.
Tarkoitus[muokkaa | muokkaa wikitekstiä]
Olio-ohjelmoinnissa, kun johdettu luokka perii kantaluokan, johdetun luokan olio voi olla viitattavissa kantaluokan tyyppisellä osoittimella tai viitteellä sen sijaan, että käytettäisiin johdetun luokan tyyppiä. Jos johdetussa luokassa korvataan kantaluokan metodeja, metodin, jota kutsutaan tällaisella viitteellä tai osoittimella, voi olla sidottu (linkitetty) joko 'varhaisessa' vaiheessa (kääntäjän toimesta) viitteen tai osoittimen deklaroidun tyypin mukaisesti tai 'myöhäisessä' vaiheessa (eli kielen suoritusjärjestelmän toimesta) viitteenä olevan olion todellisen tyypin mukaisesti.
Virtuaalifunktiot ovat määritelty 'myöhäisessä' vaiheessa. Jos kyseessä oleva funktio on 'virtuaalinen' kantaluokassa, kyseisen funktion toteutus kutsumiseen käytetään eniten johdettuun luokkaan kuuluvaa toteutusta, joka vastaa viitteenä olevan olion todellista tyyppiä, riippumatta viitteen tai osoittimen deklaroidusta tyypistä. Jos kyseessä ei ole 'virtuaalinen' funktio, menetelmä ratkaistaan 'varhaisessa' vaiheessa ja valitaan viitteen tai osoittimen deklaroidun tyypin mukaan.
C++:ssa virtuaalifunktiot määritellään lisäämällä virtual-avainsana funktion määrittelyyn kantaluokassa. Tämä muunnos periytyy kaikille johdettujen luokkien toteutuksille, joten ne voivat jatkaa toistensa korvaamista ja olla myöhäisesti sidottuja. Vaikka kantaluokan omistamat metodit kutsuisivat virtuaalista metodia, ne kutsuvat sen sijaan johdetun luokan metodia.
Kuormitus (engl. overloading) tapahtuu, kun kahdella tai useammalla metodilla yhdessä luokassa on sama nimi, mutta erilaiset parametrit. Ylikirjoitus tarkoittaa kahta metodia, joilla on sama nimi ja parametrit. Kuormitus tunnetaan myös nimellä funktiovastaavuus ja ylikirjoitus dynaamisena funktio-kartoituksena.
class Geometria
{
virtual float pinta_ala() = 0; // pure virtual
virtual int verteksilukum() { return 0; } // oletustoteutus
};
class Kolmio : public Geometria
{
virtual float pinta_ala(); // määrittely
};
float Kolmio::pinta_ala() // toteutus
{
return 42.0;
}
// kutsut virtuaalikutsujen kautta
Geometria *p = new Kolmio(); // käytetään kantaluokan osoitinta, ei tarvitse tietää varsinaista tyyppiä
float a = p->pinta_ala(); // perityn luokan toteutus
int l = p->verteksilukum(); // kantaluokan toteutus
Abstraktit luokat ja puhtaat virtuaalifunktiot[muokkaa | muokkaa wikitekstiä]
Puhdas virtuaalifunktio tai puhdas virtuaalimetodi on virtuaalinen funktio, joka on toteutettava johdetun luokan toimesta, jos johdettu luokka ei ole abstrakti. Abstrakteiksi luokiksi kutsutaan luokkia, jotka sisältävät puhtaita virtuaalisia metodeja. Abstrakteja luokkia ei voi ilmentää suoraan. Toisaalta abstraktin luokan alaluokka voidaan ilmentää suoraan, jos kaikki perityt puhtaat virtuaaliset metodit on toteutettu emoluokan toimesta tai kyseisessä luokassa. Puhtailla virtuaalisilla metodeilla on melkein aina ilmoitus eli allekirjoitus eikä määritelmää eli toteutusta.
Vaikka puhdasta virtuaalista metodia yleensä ei toteuteta luokassa, joka määrittelee sen, puhdasta virtuaalista metodia voidaan joissain kielissä, kuten C++ ja Python, sallia sisältämään toteutus niiden julistavassa luokassa, tarjoten varakäyttäytymisen tai oletuskäyttäytymisen, johon johdettu luokka voi tarvittaessa delegoida.
Puhtaita virtuaalisia metodeja voidaan käyttää silloin, kun metodin määrittelyä käytetään rajapinnan määrittämiseen - samanlainen kuin Javan käyttöliittymän avainsana. Tällaisessa käytössä johdetut luokat tarjoavat kaikki toteutukset. Tässä suunnittelumallissa rajapintana toimiva abstrakti luokka sisältää vain puhtaita virtuaalisia toimintoja, mutta ei datajäseniä tai tavallisia metodeja. C++:ssa tällaisten puhtaasti abstraktien luokkien käyttö käyttöliittyminä toimii, koska C++ tukee moniperintää. Koska monet OOP-kielet eivät kuitenkaan tue moniperintää, ne tarjoavat usein erillisen liitäntä mekanismin. Esimerkkinä on Java-ohjelmointikieli.
Katso myös[muokkaa | muokkaa wikitekstiä]
Lähteet[muokkaa | muokkaa wikitekstiä]
- Stroustrup, Bjarne: The C++ Programming Language, 4th ed.. Addison-Wesley, 2015. ISBN 0-321-56384-0.
Viitteet[muokkaa | muokkaa wikitekstiä]
- ↑ Virtual methods freepascal.org. Viitattu 26.3.2018.