Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migration of unmigrated content due to installation of a new plugin

Polymorfismi

Polymorfismilla tarkoitetaan olioiden käsittelyä kantaluokan kautta. Kantaluokka on luokka, jonka olion luokka on perinyt. Täten kantaluokka muodostaa yhteisen rajapinnan perillisten käsittelyyn.

Esimerkki 1: Olioden käsittely kantaluokan kautta.

CElain:

Code Block

// Kantaluokka CElain
Wiki Markup
h2. Polymorfismi

Polymorfismilla tarkoitetaan olioiden käsittelyä kantaluokan kautta.  Kantaluokka on luokka, jonka olion luokka on perinyt. Täten kantaluokka  muodostaa yhteisen rajapinnan perillisten käsittelyyn.

Yksi tapa hahmottaa polymorfismi on ajatella olioita substantiiveina.  Esimerkiksi esineitä, jotka ovat pöydällä: kahvikuppi, lehti, lautanen.  Kaikkiin näihin voidaan soveltaa verbejä, kuten kaataa kuppi, lukea  lehti, hajoittaa lautanen, jne. On myös olemassa verbejä, jotka  soveltuvat lähes kaikkiin substantiiveihin, kuten hae, aseta, siirrä.  Polymorfismilla tarkoitetaan 'verbejä' eli funktioita, jotka tekevät  jotain 'substantiiveille', eli erilaisille objekteille. Tämä onnistuu  ohjelmointikielissä perinnän kautta,  olioita voidaan käsitellä tietämättä eksaktia luokkaa, josta ne on  luotu, kunhan ne kaikki omaavat saman kantaluokan.

Esimerkki 1: Olioden käsittely kantaluokan kautta.

\#include <iostream>

using namespace std;

// Kantaluokka
class CElain
{
public:
&nbsp;&nbsp;&nbsp;    virtual \~CElain() {}   &nbsp; &nbsp; &nbsp; &nbsp;       // ToteutusHajoittimen toteutus tulee olla (tyhjäkin käy).
&nbsp;&nbsp;&nbsp;    virtual void Aantele() = 0;&nbsp;   // Aito virtuaalifunktio, pakko toteuttaa perillisissä.
};

CKissa:

Code Block
// Perillinen, joka toteuttaa Aantele()-funktion
class CKissa : public CElain
{
public:
&nbsp;&nbsp;&nbsp;    void Aantele() {
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cout << "Miau\!" << endl;
&nbsp;&nbsp;&nbsp; printf("Miau!\n"); }
};

CKoira:

Code Block
// Perillinen, joka toteuttaa Aantele()-funktion
class CKoira : public CElain
{
public:
&nbsp;&nbsp;&nbsp;    void Aantele() {
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cout << "Vuh\!" << endl;
&nbsp;&nbsp;&nbsp; printf("Vuh!\n"); }
};

main:

Code Block
int main()
{
&nbsp;&nbsp;&nbsp; CElain\* elain; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;    CKissa kissa;              // Luodaan CELain-tyyppinen osoitin.

&nbsp;&nbsp;&nbsp; CKissa kissa;   &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp;uusi olio CKissa-luokasta.
    CKoira koira;              // Luodaan uusi olio CKissaCKoira-luokasta.

&nbsp;&nbsp;&nbsp;    CElain* elain;             // Luodaan CELain-tyyppinen osoitin eli kantaluokan tyyppinen osoitin.

    elain = &kissa;   &nbsp; &nbsp; &nbsp; &nbsp;         // Pistetään CElain-tyyppinen osoitin&nbsp; osoittamaan olioon kissa.
&nbsp;&nbsp;&nbsp;&nbsp;    elain->Aantele(); &nbsp;&nbsp; &nbsp;          &nbsp;// Kutsutaan CKissa-luokassa toteutettua Aantele()-metodia.

&nbsp;&nbsp;&nbsp; CKoira koira; &nbsp; &nbsp; &nbsp; elain = &nbsp; &nbsp;   // Luodaa uusi olio CKoira-luokasta.

&nbsp;&nbsp;&nbsp; elain = &koira; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;koira;            // Pistetään CElain\-  tyyppinen osoitin&nbsp;  osoittamaan olioon koira.
&nbsp;&nbsp;&nbsp;    elain->Aantele();       &nbsp; &nbsp; &nbsp; // Kutsutaan CKoira-luokassa toteutettua Aantele()-metodia.
};

Esimerkissä

...

luodaan

...

oliot

...

CKissa

...

-

...

sekä

...

CKoira-luokista.

...

Lisäksi

...

luodaan

...

CElain-tyyppinen

...

osoitin.

...

Tämän

...

osoittimen

...

kautta

...

voidaan

...

käsitellä

...

kaikkia

...

CElain-luokan

...

esittelemiä

...

(public

...

ja

...

protected)

...

metodeja,

...

kuten

...

Aantele()-metodia.

...

CElain-luokka

...

toimii yhteisenä rajapintana CKissa ja CKoira -luokille.

Image Added
Kuva 1. Esimerkki 1 UML-luokkakaaviona.

Esimerkki 2: Virtuaalifunktioiden merkitys

Code Block

#include <stdio.h>

class CElain
{
public:
	        void f()  { printf("CElain::f()\n"); }
	virtual void fv() { printf("CElain::fv()\n"); }
};
Code Block

class CKissa : public CElain
{
public:
	void f()  { printf("CKissa::f()\n"); }
	void fv() { printf("CKissa::fv()\n"); }
};
Code Block

int main()
{
	printf("CElain-tyyppisen osoittimen kautta käyttäen:\n");
	CElain* e = new CKissa;
	e->f();
	e->fv();

	printf("CKissa-tyyppisen osoittimen kautta käyttäen:\n");
	CKissa* k = new CKissa;
	k->f();
	k->fv();
}

Ohjelma tulostaa::

No Format
CElain-tyyppisen osoittimen kautta käyttäen:
CElain::f()
CKissa::fv()
CKissa-tyyppisen osoittimen kautta käyttäen:
CKissa::f()
CKissa::fv()

Idea? polymorfismista

Yksi tapa hahmottaa polymorfismi on ajatella olioita substantiiveina. Esimerkiksi esineitä, jotka ovat pöydällä: kahvikuppi, lehti, lautanen. Kaikkiin näihin voidaan soveltaa verbejä, kuten kaataa kuppi, lukea lehti, hajoittaa lautanen, jne. On myös olemassa verbejä, jotka soveltuvat lähes kaikkiin substantiiveihin, kuten hae, aseta, siirrä. Polymorfismilla tarkoitetaan 'verbejä' eli funktioita, jotka tekevät jotain 'substantiiveille', eli erilaisille objekteille. Tämä onnistuu ohjelmointikielissä perinnän kautta, olioita voidaan käsitellä tietämättä eksaktia luokkaa, josta ne on luotu, kunhan ne kaikki omaavat saman kantaluokan.