Privacy Policy Cookie Policy Terms and Conditions Metoda wirtualna - Wikipedia, wolna encyklopedia

Metoda wirtualna

Z Wikipedii

Metoda wirtualna (funkcja wirtualna) to metoda która jest polimorficzna.

Spis treści

[edytuj] Przykład w C++

#include <iostream.h>
const float pi = 3.14159;
//----------------------------------------
class Figura {
  public:
    virtual float pole() const {
      return -1.0;
    }
};
//----------------------------------------
class Kwadrat : public Figura {
  public:
    Kwadrat( const float bok ) : a( bok ) {}
    float pole() const {
      return a * a;
    }
  private:
    float a; // bok kwadratu
};
//----------------------------------------
class Kolo : public Figura {
  public:
    Kolo( const float promien ) : r( promien ) {}
    float pole() const {
      return pi * r * r;
    }
  private:
    float r; // promien kola
};
//----------------------------------------
void wyswietlPole( Figura& figura ) {
  std::cout << figura.pole() << endl;
  return;
}
//----------------------------------------
int main() {
// deklaracje obiektow:
  Figura jakasFigura;
  Kwadrat jakisKwadrat( 5 );
  Kolo jakiesKolo( 3 );
  Figura* wskJakasFigura = 0; // deklaracja wskaźnika

// obiekty -------------------------------
  std::cout << jakasFigura.pole() << endl; // wynik: -1
  std::cout << jakisKwadrat.pole() << endl; // wynik: 25
  std::cout << jakiesKolo.pole() << endl; // wynik: 28.274...

// wskazniki -----------------------------
  wskJakasFigura = &jakasFigura;
  std::cout << wskJakasFigura->pole() << endl; // wynik: -1
  wskJakasFigura = &jakisKwadrat;
  std::cout << wskJakasFigura->pole() << endl; // wynik: 25
  wskJakasFigura = &jakiesKolo;
  std::cout << wskJakasFigura->pole() << endl; // wynik: 28.274...

// referencje -----------------------------
  wyswietlPole( jakasFigura ); // wynik: -1
  wyswietlPole( jakisKwadrat ); // wynik: 25
  wyswietlPole( jakiesKolo ); // wynik: 28.274...

  return 0;
}

W przykładzie znajdują się deklaracje 3 klas: Figura, Kwadrat i Kolo. W klasie Figura została zadeklarowana metoda wirtualna (słowo kluczowe virtual) virtual float pole(). Każda z klas pochodnych od klasy Figura mają zaimplementowane swoje metody float pole(). Następnie (w funkcji main) znajdują się deklaracje obiektów każdej z klas i wskaźnika mogącego pokazywać na obiekty klasy bazowej Figura.

Wywołanie metod składowych dla każdego z obiektów powoduje wykonanie metody odpowiedniej dla klasy danego obiektu. Następnie wskaźnikowi wskJakasFigura zostaje przypisany adres obiektu jakasFigura i zostaje wywołana metoda float pole(). Wynikiem jest "-1" zgodnie z treścią metody float pole() w klasie Figura. Następnie przypisujemy wskaźnikowi adres obiektu klasy Kwadrat - możemy tak zrobić ponieważ klasa Kwadrat jest klasą pochodną od klasy Figura - jest to tzw. rzutowanie w górę. Wywołanie teraz metody float pole() dla wskaznika nie spowoduje wykonania metody zgodnej z typem wskaźnika - który jest typu Figura* lecz zgodnie z aktualnie wskazywanym obiektem, a więc wykonana zostanie metoda float pole() z klasy Kwadrat (gdyż ostatnie przypisanie wskaźnikowi wartości był adres obiektu klasy Kwadrat). Analogiczna sytuacja dzieje się gdy przypiszemy wskaźnikowi adres obiektu klasy Kolo. Następnie zostaje wykonana funkcja void wyswietlPole(Figura&) która przyjmuje jako parametr obiekt klasy Figura przez 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 float Figura::pole(). Takie działanie jest spowodowane przez przyjmowanie obiektu klasy Figura przez referencję. Gdyby obiekty były przyjmowane przez wartość (parametr bez &) zostałaby wykonana 3 krotnie metoda float Figura::pole() 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 float pole() z klasy Figura.

[edytuj] "Czysta wirtualność"

Określa to, że metoda z klasy bazowej deklarująca metodę wirtualną nigdy nie powinna się wykonać. W efekcie klasa taka staje się klasą abstrakcyjną. Oznacza to tyle, iż nie jest możliwe stworzenie obiektu tej klasy. Klasa taka służy jedynie temu, by zdefiniować pewnego rodzaju interfejs i jest przeznaczona jedynie po to, by od niej dziedziczyć.

W przykładzie wyżej, o ile mogą istnieć figury będące kwadratami, kołami itp to "raczej" nie powinien istnieć żaden obiekt klasy Figura. Figura jest tutaj pewnym abstrakcyjnym określeniem, natomiast dziedziczenie po tej klasie i rozszerzeniu jej o inne elementy (dane i metody) powoduje, że mamy do czynienia już z konkretną figurą geometryczną. Metodę czysto wirtualną w języku C++ deklaruje się tak:

class Figura {
  public:
    virtual float pole() = 0;
};

Taka deklaracja metody wirtualnej zmusza jednocześnie do określenia metody float pole() na jednym z poziomów dziedziczenia. Nie jest możliwe pominięcie takiej implementacji. Jednocześnie taka deklaracja uniemożliwia stworzenie jakiegokolwike obiektu klasy Figura np.: Figura mojObiekt;.

[edytuj] Właściwości

  • Metoda wirtualna nie może być zadeklarowana jako statyczna (static).
  • Jeśli metoda wirtualna została zaimplementowana w jakimkolwiek "wyższym" poziomie dziedziczenia (w szczególności w klasie bazowej całej struktury dziedziczenia), nie jest konieczne podawanie implementacji w klasie pochodnej.
  • Jeśli w klasie jest zadeklarowana jakakolwiek metoda wirtualna, zaleca się aby destruktor w tej klasie również określić jako wirtualny (zobacz: destruktor).

C++

  • Słowo kluczowe virtual można pominąć w deklaracjach w klasach pochodnych.
  • Słowo kluczowe virtual określa się tylko w deklaracji metody, nie określa się tego w definicji (chyba że deklaracja jest jednocześnie definicją, co ma miejsce gdy implementacja metody zostanie określona w ciele klasy).

Java

  • W Javie domyślnie wszystkie metody są wirtualne. Aby jednak określić jakąś metodę jako niewirtualną należy zadeklarować metodę jako final. Słowo kluczowe final użyte w tym kontekście zabrania implementowania klasom pochodnym swoich wersji danej metody.

[edytuj] Zastosowania

  • Rozszerzalność kodu. Polimorfizm umożliwia rozszerzanie nawet skompilowanych fragmentów kodu.
    • Pozwala na rozszerzalność kodu również wtedy, gdy dostępna jest jedynie skompilowana wersja klasy bazowej.
  • Zwalnia programistę od niepotrzebnego wysiłku.
    • Programista nie musi przejmować się tym, którą z klas pochodnych aktualnie obsługuje, a jedynie tym, jakie operacje chce na tej klasie wykonać.
    • Programista myśli co ma wykonać a nie jak to coś wykonać - nie musi się przejmować szczegółami implementacyjnymi.
W innych językach
THIS WEB:

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - be - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - closed_zh_tw - co - cr - cs - csb - cu - cv - cy - da - de - diq - dv - dz - ee - el - eml - en - eo - es - et - eu - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gd - gl - glk - gn - got - gu - gv - ha - haw - he - hi - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mg - mh - mi - mk - ml - mn - mo - mr - ms - mt - mus - my - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - rm - rmy - rn - ro - roa_rup - roa_tara - ru - ru_sib - rw - sa - sc - scn - sco - sd - se - searchcom - sg - sh - si - simple - sk - sl - sm - sn - so - sq - sr - ss - st - su - sv - sw - ta - te - test - tet - tg - th - ti - tk - tl - tlh - tn - to - tokipona - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu

Static Wikipedia 2008 (no images)

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - bcl - be - be_x_old - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - co - cr - crh - cs - csb - cu - cv - cy - da - de - diq - dsb - dv - dz - ee - el - eml - en - eo - es - et - eu - ext - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gan - gd - gl - glk - gn - got - gu - gv - ha - hak - haw - he - hi - hif - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kaa - kab - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mdf - mg - mh - mi - mk - ml - mn - mo - mr - mt - mus - my - myv - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - quality - rm - rmy - rn - ro - roa_rup - roa_tara - ru - rw - sa - sah - sc - scn - sco - sd - se - sg - sh - si - simple - sk - sl - sm - sn - so - sr - srn - ss - st - stq - su - sv - sw - szl - ta - te - tet - tg - th - ti - tk - tl - tlh - tn - to - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu -

Static Wikipedia 2007:

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - be - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - closed_zh_tw - co - cr - cs - csb - cu - cv - cy - da - de - diq - dv - dz - ee - el - eml - en - eo - es - et - eu - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gd - gl - glk - gn - got - gu - gv - ha - haw - he - hi - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mg - mh - mi - mk - ml - mn - mo - mr - ms - mt - mus - my - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - rm - rmy - rn - ro - roa_rup - roa_tara - ru - ru_sib - rw - sa - sc - scn - sco - sd - se - searchcom - sg - sh - si - simple - sk - sl - sm - sn - so - sq - sr - ss - st - su - sv - sw - ta - te - test - tet - tg - th - ti - tk - tl - tlh - tn - to - tokipona - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu

Static Wikipedia 2006:

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - be - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - closed_zh_tw - co - cr - cs - csb - cu - cv - cy - da - de - diq - dv - dz - ee - el - eml - en - eo - es - et - eu - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gd - gl - glk - gn - got - gu - gv - ha - haw - he - hi - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mg - mh - mi - mk - ml - mn - mo - mr - ms - mt - mus - my - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - rm - rmy - rn - ro - roa_rup - roa_tara - ru - ru_sib - rw - sa - sc - scn - sco - sd - se - searchcom - sg - sh - si - simple - sk - sl - sm - sn - so - sq - sr - ss - st - su - sv - sw - ta - te - test - tet - tg - th - ti - tk - tl - tlh - tn - to - tokipona - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu