Создание полноценного класса из абстрактного...255

We use cookies. Read the Privacy and Cookie Policy

Подкласс абстрактного класса остаётся абстрактным, пока в нём не переопределены все чисто виртуальные функции. Класс Savings не является абстрактным, поскольку переопределяет чисто виртуальную функцию withdrawal( ) совершенно реальной. Объект класса Savings отлично знает, как реализовать функцию withdrawal( ) и куда обращаться при её вызове. То же касается и класса Checking: он не виртуальный, поскольку withdrawal( ) переопределяет чисто виртуальную функцию, определённую ранее в базовом классе.

_________________

255 стр. Глава 22. Разложение классов

Подкласс абстрактного класса, конечно, может оставаться абстрактным. Разберёмся с приведёнными ниже классами.

    class Display

    {

    public :

        virtual void initialize( ) = 0 ;

        virtual void write( char *pString ) = 0 ;

    } ;

    class SVGA : public Display

    {

        /* Сделаем обе функции-члена "реальными" */

        virtual void initialize( ) ;

        virtual void write( char *pString ) ;

    } ;

    class HWVGA : public Display

    {

        /* Переопределим только одну функцию */

        virtual void write( char *pString ) ;

    } ;

    class ThreedVGA : public HWVGA

    {

        virtual void initialize( ) ;

    } ;

    void fn( )

    {

        SVGA mc ;

        VGA vga ;

        /* Всё остальное */

    }

Класс Display, описывающий дисплеи персонального компьютера, содержит две чисто виртуальные функции: initialize( ) и write( ). Вы не можете ввести эти функции в общем виде. Разные типы видеоадаптеров инициализируются и осуществляют вывод по-разному.

Один из подклассов — SVGA — не абстрактный. Это отдельный тип видеоадаптера, и программист точно знает, как его реализовать. Таким образом, класс SVGA переопределяет обе функции — initialize( ) и write( ) — именно так, как необходимо для данного адаптера.

Ещё один подкласс — HWVGA . Программисту известно, как программировать ускоренный VGA-адаптер. Поэтому между общим классом Display и его частным случаем, ThreedVGA, который представляет собой специальный тип карт 3-D, находится ещё один уровень абстракции.

В нашем обсуждении предположим, что запись во все аппаратно ускоренные карты VGA происходит одинаково ( это не соответствует истине, но представим себе, что это так ). Чтобы правильно выразить общее свойство записи, вводится класс HWVGA, реализующий функцию write( ) ( и другие общие для HWVGA свойства ).

_________________

256 стр. Часть 4. Наследование

При этом функция initialize( ) не переопределяется, поскольку для разных типов карт HWVGA она реализуется по-разному.

Несмотря на то что функция write( ) переопределена в классе HWVGA, он всё равно остаётся абстрактным, так как функция initialize( ) всё ещё не переопределена.

Поскольку ThreedVGA наследуется от HWVGA, он должен переопределить только одну функцию, initialize( ), для того чтобы окончательно определить адаптер дисплея. Таким образом, функция fn( ) может свободно реализовать и использовать объект класса ThreedVGA.

«Замещение нормальной функцией последней чисто виртуальной функции делает класс завершённым ( т.е. неабстрактным ). Только неабстрактные классы могут быть реализованы в виде объектов.»

[Помни!]