- Baza sinifdən törəmə sinif yaratmaq və baza konstruktorunu çağırmaq
virtualvəoverrideilə metodları yenidən təyin etmək- Polimorfizmin baza göstəricisi və istinadı vasitəsilə necə işlədiyini izah etmək
- Təmiz virtual funksiyalarla abstrakt sinif yaratmaq
Oyunda döyüşçü, sehrbaz və oxatan var. Onların hamısının adı və canı var, hamısı hücum edir — amma hər biri öz üsulu ilə. Eyni kodu üç sinifdə təkrarlamaq əvəzinə ümumi hissəni bir baza sinifdə yazıb, fərqləri törəmə siniflərə vermək olar. Bu, varislikdir. Polimorfizm isə sənə hamısına eyni cür müraciət etməyə imkan verir: «hücum et!» deyirsən, hər personaj özünə uyğun hücum edir.
Varislik
class Warrior : public Character yazılışı «Warrior Character-dən törəyir» deməkdir. Törəmə sinif baza sinfin bütün üzvlərini alır və öz üzvlərini əlavə edə bilər. Baza sinfin protected üzvləri kənar koda bağlıdır, amma törəmə siniflər onları görür. Törəmə sinfin konstruktoru baza konstruktorunu inisializasiya siyahısında çağırır.
#include <iostream>
#include <string>
class Character {
public:
Character(const std::string& name, int health)
: name_(name), health_(health) {}
void status() const {
std::cout << name_ << " has " << health_ << " HP\n";
}
protected:
std::string name_;
int health_;
};
class Warrior : public Character {
public:
Warrior(const std::string& name) : Character(name, 150) {}
void shieldUp() {
health_ += 20;
std::cout << name_ << " raises a shield\n";
}
};
int main() {
Warrior w("Elvin");
w.status();
w.shieldUp();
w.status();
return 0;
}Elvin has 150 HP Elvin raises a shield Elvin has 170 HP
status() baza sinifdən hazır gəlir, shieldUp() isə yalnız Warrior-da var.Virtual funksiyalar
Törəmə obyektə baza sinfin istinadı və ya göstəricisi ilə müraciət etmək olar: hər döyüşçü həm də personajdır. Bəs belə müraciətdə hansı metod çağırılır? Adi metodda — baza sinfin versiyası, çünki seçim kompilyasiya zamanı istinadın tipinə görə edilir. Metod virtual elan olunubsa, seçim proqram işləyərkən obyektin həqiqi tipinə görə edilir.
#include <iostream>
class Base {
public:
virtual ~Base() = default;
void hello() const { std::cout << "Base::hello\n"; }
virtual void greet() const { std::cout << "Base::greet\n"; }
};
class Derived : public Base {
public:
void hello() const { std::cout << "Derived::hello\n"; }
void greet() const override { std::cout << "Derived::greet\n"; }
};
int main() {
Derived d;
const Base& ref = d;
ref.hello();
ref.greet();
return 0;
}Base::hello Derived::greet
hello virtual deyil — istinadın tipi (Base) qərar verir; greet virtualdır — obyektin həqiqi tipi (Derived) qərar verir.Abstrakt siniflər və polimorfizm
Bəzən baza sinif metodu necə yerinə yetirəcəyini bilmir: «fiqurun sahəsi» ümumi halda hesablanmır. Belə metod = 0 ilə təmiz virtual elan olunur. Ən azı bir təmiz virtual metodu olan sinif abstraktdır: ondan obyekt yaratmaq olmaz, yalnız törəmək olar. Sonra müxtəlif fiqurları bir vektorda saxlayıb onlarla eyni cür işləyə bilərik:
#include <iostream>
#include <memory>
#include <vector>
class Shape {
public:
virtual ~Shape() = default;
virtual int area() const = 0;
};
class Rect : public Shape {
public:
Rect(int w, int h) : w_(w), h_(h) {}
int area() const override { return w_ * h_; }
private:
int w_, h_;
};
class Triangle : public Shape {
public:
Triangle(int b, int h) : b_(b), h_(h) {}
int area() const override { return b_ * h_ / 2; }
private:
int b_, h_;
};
int main() {
std::vector<std::unique_ptr<Shape>> shapes;
shapes.push_back(std::make_unique<Rect>(4, 3));
shapes.push_back(std::make_unique<Triangle>(6, 5));
int total = 0;
for (const auto& s : shapes) {
std::cout << "Area: " << s->area() << '\n';
total += s->area();
}
std::cout << "Total: " << total << '\n';
return 0;
}Area: 12 Area: 15 Total: 27
Shape-in hansı növ olduğunu bilmir, amma hər obyekt öz area() metodunu çağırır — bu, polimorfizmdir.| Termin | Mənası |
|---|---|
| baza sinif | ümumi hissəni saxlayan sinif (Shape) |
| törəmə sinif | bazadan törəyib onu genişləndirən sinif (Rect) |
virtual | metod obyektin həqiqi tipinə görə seçilir |
override | virtual metodun yenidən təyin olunduğunu yoxlatdırır |
= 0 | təmiz virtual metod; sinif abstrakt olur |
Əsas fikirlər
class B : public A—BA-dan törəyir və onun üzvlərini alır.protectedüzvləri törəmə siniflər görür, kənar kod isə görmür.virtualmetod baza istinadı və ya göstəricisi ilə çağırılanda obyektin həqiqi tipinə görə seçilir.overridesəhvləri kompilyasiya zamanı tutur; polimorf bazanın destruktoruvirtualolmalıdır.= 0olan təmiz virtual metod sinfi abstrakt edir: ondan obyekt yaratmaq olmur.
Özünü yoxla
10 sual. Hər düzgün cavab XP qazandırır.
Archer sinfini Character-dən necə törətmək olar?