Metoda wirtualna: Różnice pomiędzy wersjami

[wersja nieprzejrzana][wersja nieprzejrzana]
Usunięta treść Dodana treść
m styl
→‎Przykład w [[C++]]: "Rzutowanie w dół", zamiast rzutowania w góre, ponieważ rzutujemy ze wskaznika na obiekt klasy bazowej (Figrua) na wskaznik na obiekt klasy potomnej (Kwadrat)
Linia 69:
W przykładzie znajdują się deklaracje 3 klas: <code>Figura</code>, <code>Kwadrat</code> i <code>Kolo</code>. W klasie <code>Figura</code> została zadeklarowana metoda wirtualna (słowo kluczowe ''virtual'') <code>virtual float pole()</code>. Każda z klas pochodnych od klasy <code>Figura</code> mają zaimplementowane swoje metody <code>float pole()</code>. Następnie (w funkcji main) znajdują się deklaracje obiektów każdej z klas i wskaźnika mogącego pokazywać na obiekty klasy bazowej <code>Figura</code>.
 
Wywołanie metod składowych dla każdego z obiektów powoduje wykonanie metody odpowiedniej dla klasy danego obiektu. Następnie wskaźnikowi <code>wskJakasFigura</code> zostaje przypisany adres obiektu <code>jakasFigura</code> i zostaje wywołana metoda <code>float pole()</code>. Wynikiem jest ''"-1"'' zgodnie z treścią metody <code>float pole()</code> w klasie <code>Figura</code>. Następnie przypisujemy wskaźnikowi adres obiektu klasy Kwadrat - możemy tak zrobić ponieważ klasa <code>Kwadrat</code> jest klasą pochodną od klasy <code>Figura</code> - jest to tzw. [[rzutowanie w górędół]]. Wywołanie teraz metody <code>float pole()</code> dla wskaznika nie spowoduje wykonania metody zgodnej z typem wskaźnika - który jest typu <code>Figura*</code> lecz zgodnie z aktualnie wskazywanym obiektem, a więc wykonana zostanie metoda <code>float pole()</code> z klasy <code>Kwadrat</code> (gdyż ostatnie przypisanie wskaźnikowi wartości przypisywało mu adres obiektu klasy <code>Kwadrat</code>). Analogiczna sytuacja dzieje się gdy przypiszemy wskaźnikowi adres obiektu klasy <code>Kolo</code>. Następnie zostaje wykonana funkcja <code>void wyswietlPole(Figura&)</code> która przyjmuje jako parametr obiekt klasy <code>Figura</code> przez [[referencja|referencję]]. Tutaj również zostały wykonane odpowiednie metody dla obiektów klas pochodnych a nie metoda zgodna z obiektem jaki jest zadeklarowany jako parametr funkcji czyli <code>float Figura::pole()</code>. Takie działanie jest spowodowane przez przyjmowanie obiektu klasy <code>Figura</code> przez referencję. Gdyby obiekty były przyjmowane przez wartość (parametr bez ''&'') zostałaby wykonana 3 krotnie metoda <code>float Figura::pole()</code> i 3 krotnie wyświetlona wartość ''-1''.
 
Wyżej opisane działanie zostało spowodowane przez określenie metody w klasie bazowej jako '''wirtualnej'''. Gdyby zostało usunięte słowo kluczowe ''virtual'' w deklaracji metody w klasie bazowej, zostałyby wykonane metody zgodne z typem wskaźnika lub referencji, a więc za każdym razem zostałaby wykonana metoda <code>float pole()</code> z klasy <code>Figura</code>.