Ghid complet cu teorie, exemple practice și exerciții interactive
Polimorfismul este unul dintre cei patru piloni ai programării orientate pe obiecte (OOP), alături de încapsulare, moștenire și abstractizare.
Termenul provine din greacă: poly (multe) + morphe (forme), însemnând capacitatea de a avea multiple forme.
În C++, polimorfismul permite obiectelor de tipuri diferite să fie tratate prin aceeași interfață, permițând cod mai flexibil și mai ușor de întreținut.
Rezolvat în timpul compilării. Include:
#include <iostream> using namespace std; class Calculator { public: // Funcții cu același nume dar parametri diferiți int add(int a, int b) { return a + b; } double add(double a, double b) { return a + b; } int add(int a, int b, int c) { return a + b + c; } };
class Complex { private: double real, imag; public: Complex(double r = 0, double i = 0) : real(r), imag(i) {} // Supraîncărcarea operatorului + Complex operator+(const Complex& c) { return Complex(real + c.real, imag + c.imag); } // Supraîncărcarea operatorului << friend ostream& operator<<(ostream& out, const Complex& c) { out << c.real << " + " << c.imag << "i"; return out; } };
Rezolvat în timpul execuției. Se realizează prin:
#include <iostream> #include <vector> #include <cmath> using namespace std; // Clasă de bază abstractă class Shape { protected: string name; public: Shape(const string& n) : name(n) {} // Funcții virtuale pure - face clasa abstractă virtual double area() const = 0; virtual double perimeter() const = 0; // Funcție virtuală normală virtual void display() const { cout << "Shape: " << name << endl; cout << "Area: " << area() << endl; cout << "Perimeter: " << perimeter() << endl; } // Destructor virtual - important pentru polimorfism! virtual ~Shape() {} }; // Clasă derivată - Cerc class Circle : public Shape { private: double radius; public: Circle(double r) : Shape("Circle"), radius(r) {} double area() const override { return M_PI * radius * radius; } double perimeter() const override { return 2 * M_PI * radius; } }; // Clasă derivată - Dreptunghi class Rectangle : public Shape { private: double width, height; public: Rectangle(double w, double h) : Shape("Rectangle"), width(w), height(h) {} double area() const override { return width * height; } double perimeter() const override { return 2 * (width + height); } }; // Clasă derivată - Triunghi class Triangle : public Shape { private: double a, b, c; // laturile public: Triangle(double side1, double side2, double side3) : Shape("Triangle"), a(side1), b(side2), c(side3) {} double area() const override { // Formula lui Heron double s = (a + b + c) / 2; return sqrt(s * (s - a) * (s - b) * (s - c)); } double perimeter() const override { return a + b + c; } }; int main() { // Vector de pointeri la clasa de bază vector<Shape*> shapes; // Adăugăm diferite forme shapes.push_back(new Circle(5)); shapes.push_back(new Rectangle(4, 6)); shapes.push_back(new Triangle(3, 4, 5)); // Polimorfism în acțiune! cout << "=== Demonstrație Polimorfism ===\n\n"; for (const auto& shape : shapes) { shape->display(); // Apelează metoda corectă pentru fiecare tip cout << "-----------------\n"; } // Calculăm aria totală double totalArea = 0; for (const auto& shape : shapes) { totalArea += shape->area(); } cout << "\nAria totală: " << totalArea << endl; // Eliberăm memoria for (auto& shape : shapes) { delete shape; } return 0; }
Clasă abstractă: O clasă care conține cel puțin o funcție virtuală pură.
Funcție virtuală pură: Declarată cu = 0 și TREBUIE implementată în clasele derivate.
class Animal { // Clasă abstractă public: virtual void makeSound() = 0; // Funcție virtuală pură // Poate avea și funcții normale void sleep() { cout << "Zzz..." << endl; } };
Când o clasă conține funcții virtuale, compilatorul creează o vtable (virtual table) pentru acea clasă.
class Base { public: virtual void func(int x); }; class Derived : public Base { public: // 'override' garantează că suprascrii o funcție virtuală existentă void func(int x) override; // Eroare de compilare dacă funcția nu există în bază! // void funk(int x) override; // Typo detectat! };
class Base { public: virtual void func(); }; class Derived final : public Base { // Nu poate fi moștenită public: void func() final; // Nu poate fi suprascrisă };
#include <iostream> #include <vector> #include <memory> using namespace std; // Clasă de bază pentru personaje class Character { protected: string name; int health; int damage; public: Character(const string& n, int h, int d) : name(n), health(h), damage(d) {} virtual void attack() const { cout << name << " attacks for " << damage << " damage!" << endl; } virtual void specialAbility() const = 0; virtual void displayInfo() const { cout << "[" << getClass() << "] " << name << " - HP: " << health << ", DMG: " << damage << endl; } virtual string getClass() const = 0; virtual ~Character() = default; }; // Clasă Warrior class Warrior : public Character { private: int armor; public: Warrior(const string& n) : Character(n, 150, 25), armor(50) {} void attack() const override { cout << name << " swings his mighty sword for " << damage << " damage!" << endl; } void specialAbility() const override { cout << name << " uses Shield Bash! Stuns the enemy!" << endl; } string getClass() const override { return "Warrior"; } }; // Clasă Mage class Mage : public Character { private: int mana; public: Mage(const string& n) : Character(n, 80, 40), mana(200) {} void attack() const override { cout << name << " casts Fireball for " << damage << " damage!" << endl; } void specialAbility() const override { cout << name << " casts Meteor Storm! Massive area damage!" << endl; } string getClass() const override { return "Mage"; } }; // Clasă Rogue class Rogue : public Character { private: int critChance; public: Rogue(const string& n) : Character(n, 100, 35), critChance(30) {} void attack() const override { cout << name << " strikes from the shadows for " << damage << " damage!" << endl; } void specialAbility() const override { cout << name << " vanishes! Becomes invisible!" << endl; } string getClass() const override { return "Rogue"; } }; int main() { // Folosim smart pointers pentru management automat al memoriei vector<unique_ptr<Character>> party; party.push_back(make_unique<Warrior>("Thorin")); party.push_back(make_unique<Mage>("Gandalf")); party.push_back(make_unique<Rogue>("Bilbo")); cout << "=== Party Members ===\n"; for (const auto& member : party) { member->displayInfo(); } cout << "\n=== Battle Begins! ===\n"; for (const auto& member : party) { member->attack(); member->specialAbility(); cout << endl; } return 0; }
Important: Aceste exerciții demonstrează comportamentul subtil al funcțiilor virtuale vs non-virtuale.
Analizați cu atenție ce funcții sunt virtuale și predicționați output-ul ÎNAINTE de a rula codul!
#include <iostream> using namespace std; class fairy_tale { public: void act0(){ cout << "0 Început poveste originală\n"; } virtual void act1(){ cout << "1 Prințesa întâlnește broscoiul\n"; } void act2(){ cout << "2 Prințesa sărută broscoiul\n"; } virtual void act3(){ cout << "3 Broscoiul se transformă în Prinț\n"; act4(); } virtual void act4(){ cout << "4 Și au trăit mulți ani fericiți\n"; act5(); } void act5(){ cout << "5 Sfârșit fericit\n"; } }; class unhappy_tale : public fairy_tale { public: void act0(){ cout << "0 Început poveste modificată\n"; act1(); } void act2(){ cout << "2 Prințesa atinge broscoiul\n"; act3(); } void act3(){ cout << "3 Broscoiul rămâne broscoi\n"; act4(); } void act4(){ cout << "4 Prințesa fuge îngrozită\n"; act5(); } void act5(){ cout << "5 Sfârșit nu prea fericit\n"; } };
class Restaurant { public: void openDoors() { cout << "Opening at 10 AM\n"; serve(); } virtual void serve() { cout << "Serving regular menu\n"; } void takeOrder() { cout << "Taking order\n"; cook(); } virtual void cook() { cout << "Cooking standard dish\n"; deliver(); } virtual void deliver() { cout << "Waiter delivers food\n"; } void closeDoors(){ cout << "Closing at 10 PM\n"; } }; class FastFood : public Restaurant { public: void openDoors() { cout << "24/7 Open\n"; serve(); } void serve() { cout << "Serving fast food menu\n"; takeOrder(); } void cook() { cout << "Quick frying\n"; deliver(); } void deliver() { cout << "Self-service counter\n"; } }; // Test: Ce va afișa? Restaurant* r = new FastFood(); r->openDoors(); delete r;
class Fighter { public: virtual void startCombat() { cout << "Fighter enters arena\n"; prepareWeapon(); } void prepareWeapon() { cout << "Draws sword\n"; attack(); } virtual void attack() { cout << "Basic sword slash\n"; defend(); } void defend() { cout << "Raises shield\n"; } virtual void victory() { cout << "Fighter wins!\n"; } }; class Ninja : public Fighter { public: void startCombat() { cout << "Ninja appears from shadows\n"; prepareWeapon(); } void prepareWeapon() { cout << "Throws shuriken\n"; attack(); } void attack() { cout << "Silent strike\n"; vanish(); } void vanish() { cout << "Disappears in smoke\n"; victory(); } void victory() { cout << "Ninja vanishes victoriously!\n"; } }; // Test: Predicționați output-ul Fighter* f = new Ninja(); f->startCombat(); delete f;
class CarFactory { public: void startProduction() { cout << "Starting assembly line\n"; buildChassis(); } virtual void buildChassis() { cout << "Building standard chassis\n"; installEngine(); } virtual void installEngine() { cout << "Installing V6 engine\n"; paint(); } void paint() { cout << "Painting in blue\n"; addInterior(); } virtual void addInterior() { cout << "Standard seats\n"; } }; class ElectricCarFactory : public CarFactory { public: void buildChassis() { cout << "Building lightweight chassis\n"; installEngine(); } void installEngine() { cout << "Installing electric motor\n"; installBattery(); } void installBattery() { cout << "Installing lithium battery\n"; paint(); } void addInterior() { cout << "Eco-friendly interior\n"; } }; // Ce se va afișa? CarFactory* factory = new ElectricCarFactory(); factory->startProduction(); delete factory;
class Course { public: virtual void start() { cout << "Welcome to course\n"; showIntro(); } void showIntro() { cout << "Course introduction\n"; teach(); } virtual void teach() { cout << "Teaching theory\n"; practice(); } virtual void practice() { cout << "Solving exercises\n"; } void evaluate() { cout << "Final exam\n"; certificate(); } virtual void certificate(){ cout << "Course completed!\n"; } }; class InteractiveCourse : public Course { public: void start() { cout << "Interactive session begins\n"; showIntro(); } void teach() { cout << "Live coding session\n"; practice(); } void practice() { cout << "Pair programming\n"; evaluate(); } void certificate(){ cout << "Digital badge earned!\n"; } }; // Analizați fluxul Course* c = new InteractiveCourse(); c->start(); delete c;
class Play { public: void showtime() { cout << "Curtains open\n"; act1(); } virtual void act1() { cout << "Romeo meets Juliet\n"; intermission(); } void intermission(){ cout << "15 minute break\n"; act2(); } virtual void act2() { cout << "Balcony scene\n"; finale(); } virtual void finale() { cout << "Tragic ending\n"; applause(); } void applause() { cout << "Standing ovation\n"; } }; class ModernPlay : public Play { public: void act1() { cout << "Texting instead of meeting\n"; intermission(); } void act2() { cout << "Video call scene\n"; finale(); } void finale() { cout << "Happy viral ending\n"; } }; // Ce va afișa? Play* p = new ModernPlay(); p->showtime(); delete p;
class HomeSystem { public: virtual void morning() { cout << "6 AM wake up\n"; lights(); } void lights() { cout << "Lights on\n"; heating(); } virtual void heating() { cout << "Temperature 20°C\n"; } void security() { cout << "Alarm disabled\n"; devices(); } virtual void devices() { cout << "TV on news channel\n"; } }; class SmartHome : public HomeSystem { public: void morning() { cout << "AI: Good morning!\n"; lights(); coffee(); } void heating() { cout << "Smart thermostat 22°C\n"; security(); } void coffee() { cout << "Coffee machine starts\n"; } void devices() { cout << "Playing your playlist\n"; } }; // Complex chain - predicționați! HomeSystem* home = new SmartHome(); home->morning(); delete home;
class Shop { public: void enter() { cout << "Welcome!\n"; browse(); } virtual void browse() { cout << "Looking at products\n"; select(); } virtual void select() { cout << "Choosing item\n"; pay(); } void pay() { cout << "Cash payment\n"; wrap(); } virtual void wrap() { cout << "Paper bag\n"; } void exit() { cout << "Thank you!\n"; } }; class OnlineShop : public Shop { public: void enter() { cout << "Loading website\n"; browse(); } void browse() { cout << "Scrolling catalog\n"; filter(); } void filter() { cout << "Applying filters\n"; select(); } void select() { cout << "Add to cart\n"; checkout(); } void checkout() { cout << "Proceed to checkout\n"; pay(); } void wrap() { cout << "Email confirmation\n"; exit(); } }; // Testați înțelegerea Shop* s = new OnlineShop(); s->enter(); delete s;
class MusicPlayer { public: virtual void powerOn() { cout << "Device starting\n"; loadMusic(); } void loadMusic() { cout << "Loading tracks\n"; play(); } virtual void play() { cout << "Playing music\n"; showDisplay(); } virtual void showDisplay() { cout << "LCD display\n"; } void stop() { cout << "Music stopped\n"; powerOff(); } virtual void powerOff() { cout << "Goodbye\n"; } }; class StreamingPlayer : public MusicPlayer { public: void powerOn() { cout << "Connecting WiFi\n"; login(); } void login() { cout << "Spotify login\n"; loadMusic(); } void play() { cout << "Streaming HD audio\n"; showDisplay(); } void showDisplay() { cout << "Album art display\n"; stop(); } void powerOff() { cout << "Saving playlist\n"; } }; // Ce se întâmplă aici? MusicPlayer* mp = new StreamingPlayer(); mp->powerOn(); delete mp;
class Hospital { public: void admission() { cout << "Patient registered\n"; triage(); } virtual void triage() { cout << "Nurse assessment\n"; diagnose(); } virtual void diagnose() { cout << "Doctor examination\n"; treat(); } void treat() { cout << "Standard treatment\n"; discharge(); } virtual void discharge() { cout << "Patient leaves\n"; } }; class EmergencyRoom : public Hospital { public: void admission() { cout << "EMERGENCY!\n"; triage(); } void triage() { cout << "Immediate assessment\n"; stabilize(); } void stabilize() { cout << "Vitals stabilized\n"; diagnose(); } void diagnose() { cout << "Quick diagnosis\n"; urgentCare(); } void urgentCare() { cout << "Emergency procedure\n"; treat(); } void discharge() { cout << "Transfer to ward\n"; } }; // Analizați cu atenție Hospital* h = new EmergencyRoom(); h->admission(); delete h;
class CircusAct { public: virtual void announce() { cout << "Ladies and gentlemen!\n"; prepare(); } void prepare() { cout << "Setting up stage\n"; perform(); } virtual void perform() { cout << "Basic juggling\n"; climax(); } virtual void climax() { cout << "Amazing trick!\n"; bow(); } void bow() { cout << "Take a bow\n"; applause(); } virtual void applause() { cout << "Crowd claps\n"; } }; class MagicShow : public CircusAct { public: void announce() { cout << "Behold the magic!\n"; mysterySounds(); } void mysterySounds(){ cout << "Mysterious music\n"; prepare(); } void perform() { cout << "Rabbit from hat\n"; misdirect(); } void misdirect() { cout << "Look over there!\n"; climax(); } void climax() { cout << "Person disappears!\n"; reappear(); } void reappear() { cout << "Appears in audience!\n"; bow(); } void applause() { cout << "Standing ovation!\n"; } }; // Final challenge! CircusAct* act = new MagicShow(); act->announce(); delete act;
Creați o ierarhie de clase pentru un sistem bancar:
Account cu metode virtuale pentru deposit(), withdraw(), și calculateInterest()SavingsAccount, CurrentAccount, FixedDepositImplementați o ierarhie pentru vehicule:
Vehicle cu metode pentru move(), refuel()Car, Bicycle, AirplaneCreați un sistem de operații matematice folosind polimorfism:
Operation cu metodă virtuală calculate()Addition, Subtraction, Multiplication, Divisionvirtual pentru funcții care vor fi suprascriseoverride în clasele derivate (C++11)Polimorfismul este unul dintre cele mai puternice concepte în C++, permițând cod elegant, flexibil și ușor de întreținut.
Stăpânirea polimorfismului vă va transforma dintr-un programator C++ începător într-unul avansat! 💪