Run Code
|
API
|
Code Wall
|
Users
|
Misc
|
Feedback
|
Login
|
Theme
|
Privacy
|
Blog
Polimorfizm :)
Language:
Ada
Assembly
Bash
C#
C++ (gcc)
C++ (clang)
C++ (vc++)
C (gcc)
C (clang)
C (vc)
Client Side
Clojure
Common Lisp
D
Elixir
Erlang
F#
Fortran
Go
Haskell
Java
Javascript
Kotlin
Lua
MySql
Node.js
Ocaml
Octave
Objective-C
Oracle
Pascal
Perl
Php
PostgreSQL
Prolog
Python
Python 3
R
Rust
Ruby
Scala
Scheme
Sql Server
Swift
Tcl
Visual Basic
Layout:
Vertical
Horizontal
#include <iostream> class Base { protected: // Jeżeli Value byłoby private to nie moglibyśmy go użyć w klasach dziedziczących z Base int Value; public: void SetValue(int NewValue) //Metoda niewirtualna - nie można przeciążyć jej w klasach dziedziczących { Value=NewValue; } virtual int GetValue() //Metoda wirtualna - można ją przeciążyć w klasach dziedziczących { return Value; } }; class Div_A : public Base { int GetValue() //Metoda niewirtualna - nie można przeciążyć jej w klasach dziedziczących //Ale jest wirtualna w klasie bazowej dlatego możemy ją przeciążyć { return Value+1; } }; class Div_B : public Base { int GetValue() //Jak wyżej ^ { return Value+Value; } }; class Div_C : public Base { int GetValue() //Jak wyżej ^ { return Value*Value; } }; int main() { Base* Tab[3]; //Trzy elementowa tablica wskaźników na obiekty klasy Base Tab[0] = new Div_A; Tab[1] = new Div_B; Tab[2] = new Div_C; // Jeżeli chcemy dostać obiekt, na jaki pokazuje wskaźniki zawarty np. w Tab[0] // to używamy operatora dereferencji (wyłuskania) '*' // Mamy zatem *Tab[0] // Teraz dopiero możemy wywołać metodę jaka jest zawarta wewnątrz obiektu jaki uzyskaliśmy // czyt. taki zapis Tab[0].SetValue(10); nie ma sensu bo wskąźniki Tab[0] zawiera tylko adres.. // a adres nie jest obiektem, który zawiera wewnątrz metody // Trzeba zatem najpierw "wydobyć" obiekt na jaki pokazuje wskaźnik, a dopiero potem wywołać jego metodę // A więc: (*Tab[0]).SetValue(10); // Jednak programiści uznali, że taki zapis (mimo, że jest prawidłowy) to jest brzydki i mało czytelny // Dlatego można zastąpić te nawiasy, kropki i gwiazdeczki czymś takim: Tab[1]->SetValue(10); // Właśnie wywołałem metodę obiektu na jaki pokazuje wkaźnik Tab[1] // Jako że Tab to tablica wskaźników na klasę Base to możemy wywołać przy pomocy tych wskaźników // tylko metody znajdujące się w klasie Base // Jednak jeżeli jakaś metoda w klasie Base jest wirtualna i w klasach dziedziczących po niej zostanie ona nadpisana // Oraz w rzeczywistości wskaźniki mimo, że jest typu Base zawiera obiekt dziedziczący z klasy Base // (W tym wypadku Tab[1] zawiera adres obiektu typu Div_B, a nie czystego Base) // wtedy jeżeli zostanie wywołana metoda wirtualna kompilator ogarnie, że ma zostać wywołana metoda nadpisana w klasie dziedziczącej // tak więc mając zapis: Tab[2]->SetValue(10); // Tutaj wywołujemy metodę niewirtualną; nienadpisaną, która znajduje się tylko w klasie bazowej for(int i=0; i<3; ++i) { std::cout<<Tab[i]->GetValue()<<' '; //Tutaj wywołujemy metodę GetValue, która normalnie znajduje się w klasie Base, ale posiada różne //nadpisane wersje. Zależnie od obiektu dziedziczącego wywoła inny efekt. } //Teraz naciśnij [Run it (F8)] i zobacz efekt ;) }
g++
Show compiler warnings
[
+
] Compiler args
[
+
]
Show input
Compilation time: 0.32 sec, absolute running time: 0.14 sec, cpu time: 0 sec, memory peak: 3 Mb, absolute service time: 0,46 sec
edit mode
|
history
|
discussion
11 20 100