17. Polymorphism — ko‘p shakllilik

C++ da obyektga yo‘naltirilgan dasturlashning yana bir muhim tushunchasi — polymorphism.

Polymorphism so‘zi "ko‘p shakllilik" degan ma'noni anglatadi.

Oddiy qilib aytganda, bir xil method turli classlarda turlicha ishlashi mumkin.


Oddiy misol

Tasavvur qiling, bizda Hayvon classi bor.

It:

Vov vov!

Mushuk:

Miyov!

Qush:

Chirq chirq!

deydi.

Ularning barchasida ovoz() nomli method bo‘lishi mumkin.

Lekin har bir hayvon uni boshqacha bajaradi.


Parent class

Avval Hayvon classini yaratamiz:

class Hayvon {
public:
    virtual void ovoz() {
        cout << "Hayvon ovoz chiqaryapti.";
    }
};

Bu yerda virtual so‘ziga e'tibor bering.

U methodni child classlarda o‘zgartirishga imkon beradi.


Child class

Endi It classini yaratamiz:

class It : public Hayvon {
public:
    void ovoz() override {
        cout << "Vov vov!";
    }
};

It classidagi ovoz() parent classdagi ovoz() methodining o‘rniga ishlaydi.


Yana bir child class

class Mushuk : public Hayvon {
public:
    void ovoz() override {
        cout << "Miyov!";
    }
};

Endi It va Mushuk bir xil ovoz() methodiga ega.

Lekin ular turlicha natija beradi.


To‘liq misol

#include <iostream>

using namespace std;

class Hayvon {
public:
    virtual void ovoz() {
        cout << "Hayvon ovoz chiqaryapti.";
    }
};

class It : public Hayvon {
public:
    void ovoz() override {
        cout << "Vov vov!";
    }
};

class Mushuk : public Hayvon {
public:
    void ovoz() override {
        cout << "Miyov!";
    }
};

int main() {
    It it;
    Mushuk mushuk;

    it.ovoz();
    cout << endl;

    mushuk.ovoz();

    return 0;
}

Natija:

Vov vov!
Miyov!

override nima?

override child classdagi method parent classdagi virtual methodni qayta yozayotganini bildiradi.

Masalan:

void ovoz() override {
    cout << "Vov vov!";
}

Bu:

"Men parent classdagi ovoz() methodini o‘zgartiryapman."

degan ma'noni bildiradi.


virtual nima?

virtual parent classdagi methodni child classda turlicha ishlatishga imkon beradi.

Masalan:

class Hayvon {
public:
    virtual void ovoz() {
        cout << "Hayvon";
    }
};

Keyin It:

class It : public Hayvon {
public:
    void ovoz() override {
        cout << "Vov vov!";
    }
};

Bu polymorphismning asosiy qismidir.


Parent pointer bilan ishlash

Polymorphismni yaxshiroq ko‘rish uchun pointerdan foydalanamiz.

Masalan:

Hayvon* hayvon;

Endi unga It objectini beramiz:

It it;

hayvon = &it;

Keyin:

hayvon->ovoz();

Natija:

Vov vov!

Bu juda muhim.

Pointer turi Hayvon* bo‘lsa ham, u It objectini ko‘rsatmoqda.

virtual sababli It classidagi ovoz() ishlaydi.


Yana bir misol

class Hayvon {
public:
    virtual void ovoz() {
        cout << "Hayvon";
    }
};

class It : public Hayvon {
public:
    void ovoz() override {
        cout << "Vov vov!";
    }
};

class Mushuk : public Hayvon {
public:
    void ovoz() override {
        cout << "Miyov!";
    }
};

int main() {
    Hayvon* h1;
    Hayvon* h2;

    It it;
    Mushuk mushuk;

    h1 = &it;
    h2 = &mushuk;

    h1->ovoz();
    cout << endl;

    h2->ovoz();
}

Natija:

Vov vov!
Miyov!

Bir xil:

h1->ovoz();

va:

h2->ovoz();

kodlari turli natija berdi.

Mana shu polymorphism.


Hayotiy misol

Masalan, bizda Transport degan umumiy class bor.

Transport harakatlanadi.

Lekin:

Mashina → yo‘lda yuradi
Samolyot → havoda uchadi
Kema → suvda suzadi

Ularning barchasida:

harakatlan()

methodi bo‘lishi mumkin.

Lekin har biri uni o‘ziga xos tarzda bajaradi.


Transport misoli

class Transport {
public:
    virtual void harakatlan() {
        cout << "Transport harakatlanmoqda.";
    }
};

class Mashina : public Transport {
public:
    void harakatlan() override {
        cout << "Mashina yo'lda yurmoqda.";
    }
};

class Samolyot : public Transport {
public:
    void harakatlan() override {
        cout << "Samolyot havoda uchmoqda.";
    }
};

Keyin:

Mashina mashina;
Samolyot samolyot;

Transport* t1 = &mashina;
Transport* t2 = &samolyot;

t1->harakatlan();
cout << endl;

t2->harakatlan();

Natija:

Mashina yo'lda yurmoqda.
Samolyot havoda uchmoqda.

Nima uchun polymorphism kerak?

Polymorphism dasturga moslashuvchanlik beradi.

Masalan, bizda:

Hayvon*

pointeri bo‘lsa, u:

It
Mushuk
Qush

kabi turli obyektlarni ko‘rsatishi mumkin.

Keyin:

hayvon->ovoz();

deb chaqirsak, tegishli classdagi method ishlaydi.


virtual bo‘lmasa nima bo‘ladi?

Boshlang‘ich darajada eng muhim qoida:

Agar parent classdagi methodni child classlarda turlicha ishlatmoqchi bo‘lsangiz, parent classda virtual ishlating.

Masalan:

class Hayvon {
public:
    virtual void ovoz() {
        cout << "Hayvon";
    }
};

Child class:

class It : public Hayvon {
public:
    void ovoz() override {
        cout << "Vov vov!";
    }
};

Polymorphismni oddiy eslab qolish

Quyidagini tasavvur qiling:

Hayvon
   |
   +-- It       → Vov vov!
   |
   +-- Mushuk   → Miyov!
   |
   +-- Qush    → Chirq!

Barchasida:

ovoz()

bor.

Lekin har biri o‘ziga xos ovoz chiqaradi.

Bu — polymorphism.


Amaliy mashqlar

1-mashq

Hayvon classini yarating.

Unda:

virtual void ovoz()

methodi bo‘lsin.

Keyin:

It
Mushuk

classlarini yarating.

Har birida ovoz() methodini override qiling.


2-mashq

Transport classini yarating.

Unda:

virtual void harakatlan()

methodi bo‘lsin.

Keyin:

Mashina
Samolyot

classlarini yarating.

Har birida harakatlan() methodini boshqacha yozing.


3-mashq

Shakl classini yarating.

Unda:

virtual void chiz()

methodi bo‘lsin.

Keyin:

Doira
Kvadrat

classlarini yarating.

Har birida chiz() methodini o‘zgartiring.


Muhim narsalarni eslab qoling

Polymorphism — bir xil methodning turli classlarda turlicha ishlashi.

virtual parent classdagi methodni child classlarda o‘zgartirishga imkon beradi.

override child classda parent methodi qayta yozilganini bildiradi.

Masalan:

class Hayvon {
public:
    virtual void ovoz() {
        cout << "Hayvon";
    }
};

class It : public Hayvon {
public:
    void ovoz() override {
        cout << "Vov vov!";
    }
};

Polymorphism C++ da obyektlar bilan ishlashni yanada qulay va moslashuvchan qiladi.