Metoda wirtualna - Google

Metoda wirtualna

Z Wikipedii

Skocz do: nawigacji, szukaj

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

Spis treści

[edytuj] Przykład w C++

#include <iostream>
 
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() << std::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() << std::endl; // wynik: -1
  std::cout << jakisKwadrat.pole() << std::endl; // wynik: 25
  std::cout << jakiesKolo.pole() << std::endl; // wynik: 28.274...
 
// wskazniki -----------------------------
  wskJakasFigura = &jakasFigura;
  std::cout << wskJakasFigura->pole() << std::endl; // wynik: -1
  wskJakasFigura = &jakisKwadrat;
  std::cout << wskJakasFigura->pole() << std::endl; // wynik: 25
  wskJakasFigura = &jakiesKolo;
  std::cout << wskJakasFigura->pole() << std::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 przypisywało mu 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 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 jakiegokolwiek 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.

[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.

Klucz do decyzji RPP
Na lipcowym posiedzeniu RPP członkowie Rady odsunęli decyzję o zmianie stóp procentowych w oczekiwaniu na kolejne dane. W Radzie przeważył pogląd, że kurs PLN sprzyjać będzie ograniczeniu inflacji z jednej strony, a z drugiej może pogorszyć eksport, a co za tym idzie i wzrost gospodarczy - wynika z minutes.
SpadajÄ… kontrakty na indeksy
Spadają kontrakty na amerykańskie indeksy z powodu spekulacji, że odpisy firm finansowych jeszcze wzrosną. Rosnące ceny ropy negatywnie wpływają zaś na notowania spółek lotniczych i motoryzacyjnych - podają maklerzy.
NBP podał dane o inflacji bazowej w lipcu
Inflacja bazowa po wyłączeniu cen żywności i energii - nowa miara wprowadzona w maju przez bank centralny zamiast inflacji bazowej netto - wyniosła w lipcu 2008 roku 2,2 proc. w ujęciu rocznym wobec 2,2 proc. r/r miesiąc wcześniej, podał w czwartek Narodowy Bank Polski (NBP).
RPP nie podniosła stóp z obawy o wzrost PKB
Podczas lipcowego posiedzenia Rady Polityki Pieniężnej został zgłoszony wniosek o podwyżkę stóp procentowych o 25 pb, ale nie został on przyjęty, wynika z "Opisu dyskusji na posiedzeniu decyzyjnym Rady Polityki Pieniężnej w dniu 30 lipca 2008 r." (tzw. "minutes"), opublikowanego przez NBP. Główną przyczyną odrzucenia wniosku o podwyżkę była obawa większości członków Rady o spowalniająca gospodarkę oraz zbyt szybkie umacnianie się złotego, który coraz mocniej uderza w eksporterów.
Ruszył konkurs na Innowatora Mazowsza 2008
Już tylko do 30 wrzeÅ›nia br. przedsiÄ™biorstwa stawiajÄ…ce na innowacyjne rozwiÄ…zania oraz mÅ‚odzi naukowcy mogÄ… zÅ‚ożyć wniosek w I edycji konkursu „Innowator Mazowsza”. Jest  o co walczyć, bowiem pula nagród wyniesie ponad 70 tys. zÅ‚. Celem konkursu jest wsparcie i docenienie firm proponujÄ…cych innowacyjne i nowatorskie rozwiÄ…zania.
Linki: Strona g³ówna