Выбрать главу

 

Рис. 22.5. Альтернативная иерархия классов

►Реализация абстрактных классов...253

Такое интеллектуальное упражнение, как разложение, поднимает ещё одну проблему. Вернёмся к классам банковских счетов ещё раз, а именно к общему базовому классу Account. На минуту задумайтесь над тем, как вы будете определять различные функции класса Account.

Большинство функций-членов класса Account не составят проблем, поскольку оба типа счетов реализуют их одинаково. Однако функция Account.withdrawal( ) отличается в зависимости от типа счёта. Правила снятия со сберегательного и чекового счетов различны. Мы вынуждены реализовывать Savings::withdrawal( ) не так, как Checking::withdrawal( ). Но как реализовать функцию Account::withdrawal( ) ?

Попросим банковского служащего помочь нам. Я так представляю себе эту беседу:

"Каковы правила снятия денег со счёта?" — спросите вы с надеждой.  

"Какого именно счёта, сберегательного или чекового?" — ответит он вопросом на вопрос.

"Со счёта, — скажете вы, — просто со счёта!"

_________________

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

Пустой взгляд в ответ...

Проблема в том, что такой вопрос не имеет смысла. Нет такой вещи, как "просто счёт". Все счета ( в данном примере ) должны быть чековыми или сберегательными. Концепция счёта — это абстракция, с помощью которой мы объединяем общие свойства для конкретных счетов. Это незавершённая концепция, поскольку в ней отсутствует такое важное свойство, как функции withdrawal( ) ( если вы углубитесь в детали, то найдёте и другие свойства, которых не хватает "просто счёту" ).

Абстрактный класс — это тот класс, который реализуется только в подклассе. Конкретный — тот, который не является абстрактным.

Чтобы объяснить, что я имею в виду, позвольте позаимствовать пример из мира животных. Наблюдая разные особи теплокровных и живородящих, вы можете заключить, что они все укладываются в концепцию под названием "млекопитающие". Вы можете выделить такие классы млекопитающих, как собачьи, кошачьи и приматы. Однако невозможно найти где-либо на земле просто млекопитающее. Другими словами, млекопитающие не могут содержать особь под названием "млекопитающее". Млекопитающее — это концепция высокого уровня, которую создал человек, и экземпляров-млекопитающих не существует.

Обратите внимание, что утверждать это с уверенностью я могу только по истечении некоторого времени. Ученые постоянно открывают новые виды животных. Проблема в том, что каждое существо обладает свойствами, которых не имеют другие; однако вполне вероятно, что в будущем кто-то найдёт такое свойство у других существ.

Отражая эту ситуацию, С++ даёт возможность оставлять абстрактные классы незавершёнными.

Концепция абстрактных классов...254

Абстрактный класс — это класс с одной или несколькими чисто виртуальными функциями. Прекрасно, это всё разъясняет...

Ну хорошо, чисто виртуальная функция — это функция-член без тела функции ( которого нет, например, потому, что никто не знает, как реализовать это самое тело ).

Бессмысленно спрашивать о том, каким должно быть тело функции withdrawal( ) в классе Account. Хотя, конечно, сама концепция снятия денег со счёта имеет смысл. Программист на С++ может написать функцию withdrawal( ), которая будет отражать концепцию снятия денег со счёта, но при этом данная функция не будет иметь тела, поскольку мы не знаем, как её реализовать. Такая функция называется чисто виртуальной[ 17 ] ( не спрашивайте меня, откуда взялось это название ).

Синтаксис объявления чисто виртуальной функции показан в приведённом ниже классе Account.

    /* Account — это абстрактный класс */

    class Account

    {

    protected :

        Account( Account& с ) ;

    public :

        Account( unsigned accNo , float initialBalance = 0.0F ) ;

        /* Функции доступа */

        unsigned int accountNo( ) ;

        float acntBalance( ) ;

        static int noAccounts( ) ;

        static Account *first( ) ;  

        Account *next( ) ;

        /* Функции транзакций */

вернуться

17

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