Страницы

Поиск по вопросам

воскресенье, 15 декабря 2019 г.

Зачем нужен указатель на абстрактный класс?

#cpp #классы #указатели #наследование


Не понимаю до конца суть проблемы. Посоветуйте как понять?

Мое текущее понимание понятие "Абстрактный класс":

Абстрактный класс нужен для того, чтобы запретить создавать экземпляры того, что
нельзя материализовать. Например, есть понятие "Слово". Это абстрактное понятие. Уточнение
некоторых характеристик понятия "Слово" можно уже материализовывать.

Например:

#include 
#include 
#include 

class word {
public:
    std::string _meaning;

    word() { _meaning = ""; }
    virtual void show() = 0;
};

class english_word : public word {
public:
    english_word() : word() { };
    english_word(std::string meaning) { _meaning = meaning; }

    virtual void show() override {
        std::cout << _meaning << std::endl;
    }
};


int main() {
    setlocale(LC_ALL, "RU");


    word *wrd;
    english_word ewrd("Hello");

    wrd = &ewrd; // 1
    wrd->show();

    ewrd.show(); // 2

    system("pause");
    return 0;
}


Проблема:

Сплошь и рядом при описании полиморфизма, натыкаюсь на то, что "ссылку на класс потомок
можно присвоить в указатель на базовый класс". Но зачем ? Так же сложнее.. Зачем делать
//1 если можно сразу сделать //2 ? Объясните или посоветуйте где про это почитать можно?
    


Ответы

Ответ 1



Вот вам простой пример, прямо из вашей иерархии. Но сначало небольшое отступление. У вас базовый класс word задает некое понятие, или по-другому абстрагирует некую сущность. То есть тип word задает некое самое общее поведение (общий смысл) для всевозможных слов в рамках вашей задачи. Кроме того, в рамках вашей же задачи есть особенности для слов из разных языков мира и поэтому, в частности, вы создаете другой тип уточняющий описание/поведение слов, а именно слов Английского языка (class english_word). Наследование, это специфицирование (уточнение, или изменение) поведения некоей базового понятия/сущности. Полиморфизм идет с наследованием рука об руку. Он позволяет иметь механизм работы с объектами общего типа, или общего поведения (то есть, общего набора функций, или интерефейса). Мы можем создать общий механизм работы со всеми типами-наследниками типа word. Ключевой момент - общий механизм работы! Пример. Базовый класс word имеет метод show(), характерный для всей иерархии ваших классов (в рамках вами принятой абстракции). Этот метод подразумевает, что в наследниках показ слова будет каким-то образом различен для разных языков мира. Допустим, что у вас есть некий механизм, который позволяет сделать вызов этого метода, независимо от того, какой именно тип слова (какого языка) ему передается. То есть, данный механизм будет реализовывать полиморфность, заложенную в ваш абстрактный класс word. Где-то, на просторах вашей программы есть место которое вызывает метод show у любого word, и этому месту безразлично для какого именно типа word оно это делает (ему не нужно знать конкретный тип, ему интересен только интерфейс, то есть объявленное поведение): void some_place_in_your_code(word* _a_word) { _a_word->show(); } Теперь мы можем передать в этот метод любой объект, любого наследника типа word и неважно существует этот тип на данный момент, или будет создан в будущем - поведение метода some_place_in_your_code не изменится. some_place_in_your_code( new russian_word() ); some_place_in_your_code( new english_word() ); //... some_place_in_your_code( new rohirric_word() ); //... some_place_in_your_code( new lingua_incognita_word() );

Комментариев нет:

Отправить комментарий