Olio-ohjelmointi
Tässä tehtävässä harjoitellaan periytymistä ja metodien ylikirjoittamista C++-ohjelmoinnissa. Tavoitteena on ymmärtää, miten perivä luokka voi ylikirjoittaa kantaluokan metodin, ja nähdä polymorfismi käytännössä C++:ssa.

OHJE: https://peatutor.com/cplus/index.php#overriding

Noudata käytäntöä, että kullekin luokalle luodaan oma header-tiedosto ja oma cpp-tiedosto, joilla on sama nimi kuin luokalla. Tämä hoituu automaattisesti, kun luot luokat Qt-Creatorin toiminnolla "Add New -> C++ Class". Tutustu aluksi UML-kaavion symbooleihin kts. https://peatutor.com/cplus/index.php#uml.

Harjoitus3b (perintä/ylikirjoittaminen)

Ylikirjoittaminen perivässä luokassa

  1. Luotuasi projektin, lisää siihen kantaluokka nimeltä Animal, joka sisältää virtuaalisen metodin callOut. Tämä metodi tulostaa tekstin "Eläin ääntelee."
  2. Luo kantaluokasta perivä luokka nimeltä Dog, joka ylikirjoittaa metodin callOut. Ylikirjoitetun metodin tulisi tulostaa teksti "Koira haukkuu!"
  3. Kirjoita main-funktio, jossa luodaan Animal-luokan olio ja Dog-luokan olio.
  4. Kutsu molemmissa tapauksissa callOut-metodia ja varmista, että oikea viesti tulostuu.
  5. Varmista, että luomasi oliot tuhoutuvat.

Lisätietoa

C++: Polymorfismi luokkien Animal ja Dog välillä

C++-ohjelmoinnissa, kun sinulla on perintäsuhde luokkien Animal ja Dog välillä, voit luoda ja käsitellä olion joko kantaluokan (Animal) tai perivänluokan (Dog) osoittimen kautta. Molemmilla tavoilla on etunsa. Tarkastellaan ensin molempia tapoja:

  1. Animal* dog = new Dog; (Polymorfismi)
  2. Dog* dog = new Dog; (Perivänluokan käyttö suoraan)

1. Polymorfinen olio: Animal* dog = new Dog;

Tässä käytetään kantaluokan osoitinta, mutta luodaan perivänluokan olio. Tämä tarjoaa monia etuja:

Huom! Tässä tapauksessa Animal luokan destruktori on määritettävä virtuaaliseksi.

1.1 Polymorfismi

Voit käsitellä Dog-oliota yleisemmällä Animal-tyypillä. Tämä mahdollistaa koodin kirjoittamisen siten, että se voi käsitellä mitä tahansa Animal-tyyppistä oliota (Dog, Cat, jne.), mikä lisää joustavuutta ja laajennettavuutta.

Animal* animals[] = { new Dog(), new Cat(), new Bird() };

for (int i = 0; i < 3; i++) {
    animals[i]->callOut();  // Jokainen eläin toteuttaa oman luokkansa callOut-metodin
}

1.2 Yleisemmät funktiot

Funktiot voivat käsitellä Animal-tyyppisiä olioita ilman, että niiden tarvitsee tietää perivää luokkaa:

void handleAnimal(Animal* animal) {
    animal->callOut();  // Polymorfinen kutsu
}

1.3 Laajennettavuus

Voit lisätä uusia eläinlajeja (Cat, Bird, jne.) ilman, että sinun tarvitsee muuttaa vanhaa koodia, joka käyttää kantaluokkaa (Animal).

2. Perivänluokan olio: Dog* dog = new Dog;

Tässä käytetään perivänluokan osoitinta. Tämä voi olla hyödyllistä seuraavissa tilanteissa:

2.1 Perivänluokan ominaisuuksien käyttö

Jos haluat käyttää Dog-luokan erityisiä metodeja tai jäsenmuuttujia, jotka eivät ole kantaluokassa, sinun täytyy käyttää Dog-osoitinta:

Dog* dog = new Dog();
 dog->getOwner();  // Ominaisuus, joka on vain Dog-luokassa, ei Animal-luokassa

2.2 Ei tarvitse virtuaalisia funktioita

Jos et tarvitse polymorfismia, suora Dog-osoitin voi olla tehokkaampi, koska se ei aiheuta ylimääräistä suorituskykykustannusta virtuaalifunktiotaulun (vtable) käytöstä (vtable on taulukko, joka sisältää osoittimet virtuaalisiin metodeihin).

Yhteenveto

Ominaisuus Animal* dog = new Dog; Dog* dog = new Dog;
Polymorfismi Kyllä Ei
Koodin joustavuus ja laajennettavuus Kyllä Ei
Perivänluokan metodit käytettävissä Ei ilman tyyppimuunnosta Kyllä
Suorituskyky Hieman hitaampi (virtuaalitaulu) Hieman nopeampi

Milloin käyttää Animal* ja milloin Dog*?

  • Käytä Animal*, kun haluat hyödyntää polymorfismia ja käsitellä erilaisia eläinluokkia samalla tavalla.
  • Käytä Dog*, kun tiedät tarkalleen, että työskentelet vain Dog-olioiden kanssa ja haluat käyttää sen erityisiä metodeja.

Esimerkki 1: Polymorfismi


Animal* animal = new Dog();  // Animal-osoitin, mutta Dog-käytössä
animal->callOut();         // Kutsuu Dog:n toteuttamaa callOut-metodia

Esimerkki 2: Suora käyttö

Dog* dog = new Dog();
 dog->getOwner();  // Erityinen Dog-metodi



Toggle Menu