T740103 Olio-ohjelmointi Osa 5: Periytyminen ja polymorfismi Jukka Jauhiainen OAMK Tekniikan yksikkö 2010

Samankaltaiset tiedostot
Olio-ohjelmoinnissa luokat voidaan järjestää siten, että ne pystyvät jakamaan yhteisiä tietoja ja aliohjelmia.

815338A Ohjelmointikielten periaatteet Harjoitus 5 Vastaukset

T Olio-ohjelmointi Osa 3: Luokka, muodostin ja hajotin, this-osoitin Jukka Jauhiainen OAMK Tekniikan yksikkö 2010

1. Olio-ohjelmointi 1.1

Virtuaalifunktiot ja polymorfismi

Luokat. Luokat ja olio-ohjelmointi

Sisällys. JAVA-OHJELMOINTI Osa 6: Periytyminen ja näkyvyys. Luokkahierarkia. Periytyminen (inheritance)

Tehtävä 1. TL5302 Olio-ohjelmointi Koe Malliratkaisuja. Tässä sekä a)- että b)-kohdan toimiva ratkaisu:

Harjoitus Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

Olio-ohjelmointi Syntaksikokoelma

Sisällys. 9. Periytyminen Javassa. Periytymismekanismi Java-kielessä. Periytymismekanismi Java-kielessä

9. Periytyminen Javassa 9.1

9. Periytyminen Javassa 9.1

Aalto Yliopisto T Informaatioverkostot: Studio 1. Oliot ja luokat Javaohjelmoinnissa

12 Mallit (Templates)

Luokassa määriteltävät jäsenet ovat pääasiassa tietojäseniä tai aliohjelmajäseniä. Luokan määrittelyyn liittyvät varatut sanat:

C++11 Syntaksi. Jari-Pekka Voutilainen Jari-Pekka Voutilainen: C++11 Syntaksi

Sisällys. 9. Periytyminen Javassa. Periytymismekanismi Java-kielessä. Periytymismekanismi Java-kielessä

Tenttikysymykset. + UML-kaavioiden mallintamistehtävät

Oliosuunnitteluesimerkki: Yrityksen palkanlaskentajärjestelmä

Olio-ohjelmointi Javalla

Periytyminen (inheritance)

Periytyminen. Luokat ja olio-ohjelmointi

A) on käytännöllinen ohjelmointitekniikka. = laajennetaan aikaisemmin tehtyjä luokkia (uudelleenkäytettävyys)

C++ rautaisannos. Kolme tapaa sanoa, että tulostukseen käytetään standardikirjaston iostreamosassa määriteltyä, nimiavaruuden std oliota cout:

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Taulukot & Periytyminen

1 Tehtävän kuvaus ja analysointi

Operaattoreiden ylikuormitus. Operaattoreiden kuormitus. Operaattoreiden kuormitus. Operaattoreista. Kuormituksesta

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Rajapinnat ja sisäluokat

815338A Ohjelmointikielten periaatteet

UML -mallinnus LUOKKAKAAVIO EERO NOUSIAINEN

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen

TIE Ohjelmistojen suunnittelu

Osoitin ja viittaus C++:ssa

812336A C++ -kielen perusteet,

Geneeriset luokat. C++ - perusteet Java-osaajille luento 6/7: Template, tyyppi-informaatio, nimiavaruudet. Geneerisen luokan käyttö.

C# olio-ohjelmointi perusopas

Mikä yhteyssuhde on?

Olio-ohjelmointi 2. välikoe HYV5SN

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. X Poikkeusten käsittelystä

Olio-ohjelmoinnin toteuttaminen Fortran 90 -kielellä

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. IV Periytyminen ja monimuotoisuus

2. Olio-ohjelmoinista lyhyesti 2.1

Osa III. Olioiden luominen vapaalle muistialueelle

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. VII Suunnittelumallit Adapter ja Composite

Demo 6 vastauksia. 1. tehtävä. #ifndef #define D6T1 H D6T1 H. #include <iostream> using std::ostream; using std::cout; using std::endl;

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä. Tiedonkätkentä. Aksessorit. 4.2

Esimerkkiprojekti. Mallivastauksen löydät Wroxin www-sivuilta. Kenttä Tyyppi Max.pituus Rajoitukset/Kommentit

Java kahdessa tunnissa. Jyry Suvilehto

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Pakkaukset ja määreet

Javan perusteita. Janne Käki

13 Operaattoreiden ylimäärittelyjä

on ohjelmoijan itse tekemä tietotyyppi, joka kuvaa käsitettä

Olion elinikä. Olion luominen. Olion tuhoutuminen. Olion tuhoutuminen. Kissa rontti = null; rontti = new Kissa();

YHTEYSSUHDE (assosiation)

Ohjelmointi 2 / 2010 Välikoe / 26.3

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä ja ulkopuolelta. Attribuuttien arvojen käsittely aksessoreilla. 4.2

12. Monimuotoisuus 12.1

Ohjelmoinnin jatkokurssi, kurssikoe

Sisällys. 1. Omat operaatiot. Yleistä operaatioista. Yleistä operaatioista

Kompositio. Mikä komposition on? Kompositio vs. yhteyssuhde Kompositio Javalla Konstruktorit set-ja get-metodit tostring-metodi Pääohjelma

Ohjelman virheet ja poikkeusten käsittely

12. Monimuotoisuus 12.1

Taulukot. Jukka Harju, Jukka Juslin

Metodien tekeminen Javalla

JAVA-PERUSTEET. JAVA-OHJELMOINTI 3op A JAVAN PERUSTEET LYHYT KERTAUS JAVAN OMINAISUUKSISTA JAVAN OMINAISUUKSIA. Java vs. C++?

1. Mitä tehdään ensiksi?

Mallit standardi mallikirjasto parametroitu tyyppi

P e d a c o d e ohjelmointikoulutus verkossa

TIE Ohjelmistojen suunnittelu

Ohjelmointitaito (ict1td002, 12 op) Kevät Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen

4. Luokan testaus ja käyttö olion kautta 4.1

1. Omat operaatiot 1.1

TIE Samuel Lahtinen. Lyhyt UML-opas. UML -pikaesittely

UML ja luokkien väliset suhteet

\+jokin merkki tarkoittaa erikoismerkkiä; \n = uusi rivi.

Rajapinta (interface)

Sisällys. 18. Abstraktit tietotyypit. Johdanto. Johdanto

15. Ohjelmoinnin tekniikkaa 15.1

Ohjelmointi 2, välikoe

Apuja ohjelmointiin» Yleisiä virheitä

TIE Ohjelmistojen suunnittelu. Kopiointia ja sijoittelua

15. Ohjelmoinnin tekniikkaa 15.1

Luokat ja oliot. Ville Sundberg

private TreeMap<String, Opiskelija> nimella; private TreeMap<String, Opiskelija> numerolla;

Luokka Murtoluku uudelleen. Kirjoitetaan luokka Murtoluku uudelleen niin, että murtolukujen sieventäminen on mahdollista.

Sisällys. JAVA-OHJELMOINTI Osa 7: Abstrakti luokka ja rajapinta. Abstraktin luokan idea. Abstrakti luokka ja metodi. Esimerkki

Rajapinnasta ei voida muodostaa olioita. Voidaan käyttää tunnuksen tyyppinä. Rajapinta on kuitenkin abstraktia luokkaa selvästi abstraktimpi tyyppi.

Ohjelmistojen mallintaminen luokkamallin lisäpiirteitä

Sisällys. Metodien kuormittaminen. Luokkametodit ja -attribuutit. Rakentajat. Metodien ja muun luokan sisällön järjestäminen. 6.2

TIE Ohjelmistojen suunnittelu. Kopiointia ja sijoittelua

14. Poikkeukset 14.1

Olio-ohjelmointi: Luokkien toteuttaminen. Jukka Juslin

Ohjelmistojen mallintaminen Luokkakaaviot Harri Laine 1

Pong-peli, vaihe Aliohjelman tekeminen. Muilla kielillä: English Suomi. Tämä on Pong-pelin tutoriaalin osa 3/7. Tämän vaiheen aikana

ITKP102 Ohjelmointi 1 (6 op)

Olio-ohjelmointi Suunnittelumallit Adapter ja Composite. 1. Adapter

18. Abstraktit tietotyypit 18.1

Abstraktit tietotyypit ja olio-ohjelmointi

Transkriptio:

12. Periytyminen Johdantoa Käytännössä vähänkään laajemmissa ohjelmissa joudutaan laatimaan useita luokkia, joiden pitäisi pystyä välittämään tietoa toisilleen. Ohjelmien ylläpidon kannalta olisi lisäksi suotavaa, että samaa koodia ei ole useassa eri paikassa. Olio-ohjelmoinnissa luokat voidaan järjestää siten, että ne pystyvät jakamaan yhteisiä tietoja ja aliohjelmia. Periytyminen tarkoittaa, että jonkin ns. kantaluokan (base class) ominaisuuksia voidaan periyttää (inherit) kantaluokasta johdetulle luokalle (derived class). Kokonaisuudessa luokkien periytyminen on varsin monimutkaista. Tarkastellaan tällä kurssilla yksinkertaisinta tapausta eli ns. palveluliittymän periytymistä eli public-periytymistä. Tarkemmin periytyminen on käsitelty esimerkiksi Markun materiaalissa ja Hietasen kirjassa. Kun tietokoneohjelmalla pyritään mallintamaan jotain reaalimaailman ilmiötä, päädytään väistämättä määrittelemään erilaisia käsitteitä ja niiden välisiä suhteita. Yritäpä esimerkiksi mallintaa, mikä auto on. Pian joudut turvautumaan sellaisiin käsitteisiin kuten pyörä, moottori, kuljettaja, jalankulkija, kuorma-auto, henkilöauto, linja-auto, ambulanssi, tie, öljy jne Olio-ohjelmoinnissa luokkia käytetään reaalimaailman käsitteiden kuvaamiseen. Kysymys kuuluukin, miten käsitteiden välisiä yhteyksiä kuvataan? Miten pyörä liittyy autoon? Entä moottori jne? Periytymisen avulla voidaan ilmaista käsitteiden välisiä hierarkkisia yhteyksiä ohjelmointikielellä. Esimerkiksi ympyrällä, suorakulmiolla ja kolmiolla on jotain yhteistä. Kaikki ovat geometrisia muotoja, joilla on tietty pinta-ala. Kaikkien pinta-ala kuitenkin tunnetusti lasketaan eri tavalla. Ohjelmassa täytyy siten määritellä kolme luokkaa: Circle, Triangle ja Shape. Luokka Shape on kantaluokka ja Circle ja Triangle ovat kantaluokasta johdettuja luokkia. Johdetut luokat ja public-periytymistapa 1

Tarkastellaan ohjelmaa, jonka on tarkoitus ylläpitää yrityksen henkilötietojärjestelmää. Yrityksessä on kahdenlaisia työntekijöitä, tavallisia työntekijöitä ja eri tason johtajia. Luokan määritys voisi näyttää tältä: class duunari { string etunimi,sukunimi; int osasto; double palkka; void duunaile(); duunari(); ~duunari(); class pomo : public duunari { private: int alaistenlkm; void johda(); pomo(); ~pomo(); Johtaja on välttämättä aina myös yrityksen palkkalistoilla oleva työntekijä, mutta kaikki työntekijät eivät ole johtajia. Johtajaan siis liittyy tietoja, joita työntekijään ei liity, esimerkiksi alaisten lukumäärä. Johtaja on työntekijä, johon liittyy joitakin lisäominaisuuksia. Englanninkielessä puhutaan is-a-periytymisestä: A manager is an employee. Olio-ohjelmoinnin käsitteillä asia voidaan esittää siten, että luokka pomo on johdettu luokasta duunari. Toisin päin ilmaistuna, luokka duunari on kantaluokka luokalle pomo. Luokka pomo sisältää (perii) kaikki luokan duunari ominaisuudet ja siihen sisältyy omia ominaisuuksia, joita ei kuulu luokkaan duunari. Johdettu luokka on siis yleensä aina suurempi kuin kantaluokka. Se sisältää enemmän tieto- ja / tai aliohjelmajäseniä. Kantaluokan ja johdetun luokan ohella käytetään termejä yliluokka ja aliluokka. Public-periytymistavan yleinen muoto on: class yliluokka { private: 2

T740103 Olio-ohjelmointi class aliluokka : public yliluokka { private: Luokan määrittelyssä esiintyy uusi avainsana protected. Sana protected määrittelee luokan suojatun jäsenen. Yksityisen ja suojatun jäsenen välinen ero on siinä, miten kyseisestä luokasta johdetut luokat pystyvät käsittelemään niiden sisältämiä tietoja: Suojattuja jäseniä (protected) voivat käsitellä myös luokasta johdetut luokat. Yksityisiä jäseniä (private) voi käsitellä vain luokka itse, ei siitä johdetut luokat. Julkisia jäseniä (public) voi käsitellä mikä tahansa, myös luokkaan kuulumaton aliohjelma, mukaan lukien main(). Edellä siis luokan duunari kaikki tietojäsenet on määriteltävä suojatuiksi, koska siitä johdetun luokan pomo pitää pystyä käsittelemään duunarin tietoja. Sen sijaan luokasta pomo ei ole johdettu luokkia, eikä duunarin tarvitse tietää, montako alaista pomolla on. Siksi luokan pomo ainoa tietojäsen alaistenlkm pitää määritellä yksityiseksi. Alla olevaan taulukkoon on koottu, kenellä on oikeus käsitellä luokan jäseniä (joko tieto- tai aliohjelmajäseniä). Access public protected private Saman luokan jäsenet kyllä kyllä kyllä Johdettujen luokkien jäsenet kyllä Kyllä ei Ei-jäsenet kyllä ei ei Kanta- ja johdettu luokka käsittelevät kumpikin omia yksityisiä jäseniään. Johdetun luokan aliohjelmissa voidaan viitata kantaluokan protected- ja public-määreen jäljessä esiteltyihin jäseniin. Public-periytymistapa 3

pitää kantaluokan jäsenten näkyvyyssäännöt johdetussa luokassa ennallaan. Jos johdetusta luokasta periytetään uusi johdettu luokka, näkee uusi luokka ylimmän luokan protected-jäsenet myös oman kantaluokkansa protected-jäseninä. Vastaavasti näkyvät ylimmän luokan public-jäsenet. Kanta- ja johdettu luokka voivat sisältää tarvittaessa samannimisiä tietoja ja aliohjelmia. Tässä tapauksessa johdettu luokka peittää kantaluokan vastaavannimisen aliohjelman. Esimerkki: Monikulmio Mitä yhteistä on suorakulmiolla ja kolmiolla? Molemmat ovat monikulmioita (engl. polygon) ja molempien pinta-ala lasketaan korkeuden ja leveyden avulla. Tämä yhteys voitaisiin esittää luokkahierarkiana CPolygon on kantaluokka, josta voidaan periyttää johdetut luokat CRectangle (suorakulmio) ja Ctriangle (kolmio). Seuraavassa on esitetty luokan CPolygon määrittely: { width=a; height=b; 4

Luokka sisältää suojatut tietojäsenet width ja height, sekä yhden julkisen aliohjelmajäsenen set_values(). Johdetut luokat perivät kantaluokan jäsenet, joten niihin tarvitsee erikseen kirjoittaa ainoastaan metodit, jotka laskevat pinta-alan (pinta-alan laskentahan on tunnetusti erilainen kolmiolle ja suorakulmiolle): class CRectangle: public CPolygon { class CTriangle: public CPolygon { { return (width * height / 2); Pääohjelmassa oliota voidaan kutsua esimerkiksi seuraavasti: int main () { CRectangle rect; CTriangle trgl; rect.set_values (4,5); trgl.set_values (4,5); cout << rect.area() << endl; cout << trgl.area() << endl; return 0; Edellä luodaan suorakulmio-olio rect ja kolmio-olio trgl. Molemmat voivat käyttää kantaluokassa määriteltyä metodia set_values(). Molemmilla oliolla on kuitenkin oma pinta-alan laskentametodinsa. Private- ja protected-periytyminen Edellä tarkasteltiin public-periytymistä. class aliluokka : public yliluokka { private: 5

Public-periytymisessä johdetun luokan jäsenillä on samat suojausmekanismit kuin kantaluokassa. Jos jäsen on kantaluokassa tyyppiä protected, on se myös johdetussa luokassa protected. Edellä kaksoispisteen jäljessä oleva määre kertoo luokan jäsenten minimisuojaustason. Jos periytyminen määritellään olevan tyyppiä protected, ovat kaikki johdetun luokan jäsenet vähintään tyyppiä protected (kantaluokan public-jäsenet muuttuvat protected-tyyppisiksi). Jos periytyminen määritellään olevan tyyppiä private, ovat kaikki johdetun luokan jäsenet tyyppiä private (siis kantaluokan sekä public- että protected-jäsenet muuttuvat private-tyyppisiksi). Johdetulla luokalla voi olla omia jäseniä, jotka eivät periydy kantaluokasta, joilla on löyhemmät suojausominaisuudet. Mitä tapahtuu, jos CRectangle määriteltäisiin periytyväksi luokasta CPolygon protected-tyyppisesti? class CRectangle: protected CPolygon { CPolygon sisältää julkisen aliohjelmajäsenen set_values(). Määrityksen jälkeen se muuttuisi protected-tyyppiseksi. Onko tällä muutoksella vaikutuksia ohjelman toimintaan? Vastaavasti määrittely: class CRectangle: private CPolygon { muuttaisi set_values()-metodin private-tyyppiseksi. Entä onko tällä vaikutusta ohjelman toimintaan? Kummassakaan edellä mainitussa tapauksessa set_values()-metodia ei enää voi kutsua pääohjelmasta, koska main() ei ole luokan CPolygon jäsen eikä aliluokka. Käytännössä public-periytyminen on ylivoimaisesti yleisin. 6

13. Polymorfismi Eräs johdetun luokan keskeinen ominaisuus on, että osoitin johdettuun luokkaan on tyyppiyhteensopiva kantaluokkaan osoittavan osoittimen kanssa. Seuraavassa ohjelmassa on luotu kaksi osoitinta luokkaan CPolygon (ppoly1 ja ppoly2) ja asetetaan ne osoittamaan luokan olioihin rect ja trgl. Tämä on mahdollista, koska sekä luokat CRectangle että CTriangle on johdettu CPolygon-luokasta. Ainoa rajoitus on, että koska ppoly1 ja ppoly2 ovat tyyppiä CPolygon, niillä on käytössä vain ne palvelut, jotka CPolygon tarjoaa, ei johdettujen luokkien palvelut. Esimerkiksi siis pinta-alan laskenta ei ole näiden osoittimien avulla mahdollista, koska ne määritellään johdetuissa luokissa. Jos pinta-ala haluttaisiin laskea luokkaan CPolygon osoittavien osoittimien avulla, pitäisi laskenta olla määritelty tässä luokassa. Ongelmaksi muodostuu, että pinta-ala on erilainen kolmiolla ja suorakulmiolle. Ongelma on mahdollista ratkaista virtuaalisten jäsenten avulla. // pointers to base class #include <iostream> using namespace std; { width=a; height=b; class CRectangle: public CPolygon { int area () class CTriangle: public CPolygon { int area () { return (width * height / 2); int main () { CRectangle rect; CTriangle trgl; CPolygon * ppoly1 = &rect; CPolygon * ppoly2 = &trgl; ppoly1->set_values (4,5); ppoly2->set_values (4,5); 7

cout << rect.area() << endl; cout << trgl.area() << endl; return 0; Virtuaaliset luokan jäsenet Luokan jäsen, joka voidaan määritellä uudelleen johdetussa luokassa on nimeltään virtuaalinen jäsen. Tällaisen jäsenen eteen tulee luokan määrittelyssä avainsana virtual. // virtual members #include <iostream> using namespace std; { width=a; height=b; virtual int area () { return (0); class CRectangle: public CPolygon { int area () class CTriangle: public CPolygon { int area () { return (width * height / 2); int main () { CRectangle rect; CTriangle trgl; CPolygon poly; CPolygon * ppoly1 = &rect; CPolygon * ppoly2 = &trgl; CPolygon * ppoly3 = &poly; ppoly1->set_values (4,5); ppoly2->set_values (4,5); ppoly3->set_values (4,5); 8

cout << ppoly1->area() << endl; cout << ppoly2->area() << endl; cout << ppoly3->area() << endl; return 0; Nyt jokaisella luokalla (Cpolygon, CRectangle ja CTriangle) on samat jäsenet: width, height, set_values() ja area(). Jäsenfunktio area() on määritelty virtuaaliseksi kantaluokassa, koska jokainen johdettu luokka toteuttaa oman pinta-alan laskentansa. Jos avainsana virtual poistettaisiin arean edestä, olisivat kaikki pinta-alat nollia. Tämä siksi, että ppoly1, ppoly2 ja ppoly3 ovat osoittimia kantaluokkaan CPolygon, jossa pinta-alaksi tulee aina nolla. Toisin sanoen: Jos osoitin on kantaluokan tyyppiä mutta osoittaa johdetun luokan olioon, avainsana virtual mahdollistaa oikean jäsenfunktion kutsumisen. Luokka, jossa on tai joka on perinyt virtuaalisen funktion, sanotaan polymorfiseksi luokaksi. Abstraktit kantaluokat Abstraktit kantaluokat ovat hyvin samanlaisia kuin edellisen esimerkin CPolygon-luokka. Erona on, että abstraktissa kantaluokassa ei tarvitse määritellä area()-funktion toimintaa. Sen sijaan luokan nimen jälkeen kirjoitetaan luokan määrittelyssä =0. Abstrakti kantaluokka CPolygon näyttäisi tältä: // abstract class CPolygon { width=a; height=b; virtual int area () =0; Funktiolle area() ei siis ole määritelty toimintaa. Tällaista funktiota kutsutaan puhtaaksi virtuaaliseksi funktioksi. Kaikkia sellaisia luokkia, jotka sisältävät ainakin yhden puhtaan virtuaalisen funktion sanotaan abstrakteiksi kantaluokiksi. Pääasiallinen ero aikaisempaan polymorfiseen luokkaan on, että koska abstraktissa kantaluokassa ainakin yhdellä jäsenfunktiolla ei ole määritystä, abstraktista kantaluokasta ei voi suoraan luoda olioita. Vaikka luokasta ei voikaan luoda olioita, voidaan luokkaan osoittaa osoittimilla. Siten määritys CPolygon poly; 9

On virheellinen jos CPolygon on abstrakti kantaluokka, mutta osoittimet CPolygon * ppoly1; CPolygon * ppoly2; ovat OK. Näillä osoittimilla voidaan osoittaa johdettujen luokkien olioihin. // abstract base class #include <iostream> using namespace std; { width=a; height=b; virtual =0; class CRectangle: public CPolygon { class CTriangle: public CPolygon { { return (width * height / 2); int main () { CRectangle rect; CTriangle trgl; CPolygon *ppoly1 = &rect; CPolygon *ppoly2 = &trgl; ppoly1->set_values (4,5); ppoly2->set_values (4,5); cout << ppoly1->area() << endl; cout << ppoly2->area() << endl; return 0; Edellistä ohjelmaa tutkailemalla havaitaan, että voimme viitata sekä luokkaan CRectangle että luokkaan CTriangle osoittimella luokkaan CPolygon. On esimerkiksi mahdollista tehdä 10

jäsenfunktio luokkaan CPolygon, joka tulostaa näytölle olion pinta-alan, vaikka luokassa itsessään ei ole pinta-alan laskentaa: // pure virtual members can be called // from the abstract base class #include <iostream> using namespace std; { width=a; height=b; virtual =0; void printarea (void) { cout << this->area() << endl; class CRectangle: public CPolygon { class CTriangle: public CPolygon { { return (width * height / 2); int main () { CRectangle rect; CTriangle trgl; CPolygon *ppoly1 = &rect; CPolygon *ppoly2 = &trgl; ppoly1->set_values (4,5); ppoly2->set_values (4,5); ppoly1->printarea(); ppoly2->printarea(); return 0; Viimeisessä esimerkissä olioille varataan muistia dynaamisesti: // dynamic allocation and polymorphism #include <iostream> using namespace std; 11

{ width=a; height=b; virtual =0; void printarea (void) { cout << this->area() << endl; class CRectangle: public CPolygon { class CTriangle: public CPolygon { { return (width * height / 2); int main () { CPolygon *ppoly1 = new CRectangle; CPolygon *ppoly2 = new CTriangle; ppoly1->set_values (4,5); ppoly2->set_values (4,5); ppoly1->printarea(); ppoly2->printarea(); delete ppoly1; delete ppoly2; return 0; Huomaa, että vaikka osoittimien ppoly1 ja ppoly2 tyyppi on CPolygon, mutta kun niille allokoidaan muistia new-metodilla, ovat tyypit CRectangle ja CTriangle. Tällöin siis käytännössä ppoly1 on tyyppiä CRectangle ja ppoly2 tyyppiä CTriangle. 12