Бьерн Страуструп - Язык программирования С++. Вступление, глава 1
Страница 21. Объектно-ориентированное программирование


 

1.2.5  Объектно-ориентированное программирование

    Проблема состоит в том, что мы не различаем общие свойства фигур
(например, фигура имеет цвет, ее можно нарисовать и т.д.) и свойства
конкретной фигуры (например, окружность - это такая фигура, которая имеет
радиус, она изображается с помощью функции, рисующей дуги и т.д.). Суть
объектно-ориентированного программирования в том, что оно позволяет
выражать эти различия и использует их. Язык, который имеет конструкции для
выражения и использования подобных различий, поддерживает
объектно-ориентированное программирование. Все другие языки не
поддерживают его.  Здесь основную роль играет механизм наследования,
заимствованный из языка Симула. Вначале определим класс, задающий общие
свойства всех фигур:

    class shape
    {
      point center;
      color col;
      // ...
      public:
      point where () { return center; }
      void move ( point to ) { center = to; draw(); }
      virtual void draw ();
      virtual void rotate ( int );
      // ...
    };

    Те функции, для которых можно определить заявленный интерфейс, но
реализация которых (т.е. тело с операторной частью) возможна только для
конкретных фигур, отмечены служебным словом virtual (виртуальные). В
Симуле и С++ виртуальность функции означает: "функция может быть
определена позднее в классе, производном от данного". С учетом такого
определения класса можно написать общие функции, работающие с фигурами:

          void rotate_all ( shape v [], int size, int angle )
          // повернуть все элементы массива "v" размера "size"
          // на угол равный "angle"
          {
            int i = 0;
            while ( i<size )
            {
              v [ i ] . rotate ( angle );
              i = i + 1;
            }
          }

    Для определения конкретной фигуры следует указать, прежде всего, что
это - именно фигура и задать ее особые свойства (включая и виртуальные
функции):

          class circle : public shape
          {
              int radius;
          public:
              void draw () { /* ... */ };
              void rotate ( int ) {}  // да, пока пустая функция
          };

    В языке С++ класс circle называется производным по отношению к классу
shape, а класс shape называется базовым для класса circle.  Возможна
другая терминология, использующая названия "подкласс" и "суперкласс" для
классов circle и shape соответственно.  Теперь парадигма программирования
формулируется так:

    Определите, какой класс вам необходим; предоставьте полный набор
операций для каждого класса; общность классов выразите явно с помощью
наследования.

    Если общность между классами отсутствует, вполне достаточно абстракции
данных. Насколько применимо объектно-ориентированное программирование для
данной области приложения определяется степенью общности между разными
типами, которая позволяет использовать наследование и виртуальные функции.
В некоторых областях, таких, например, как интерактивная графика, есть
широкий простор для объектно-ориентированного программирования. В других
областях, в которых используются традиционные арифметические типы и
вычисления над ними, трудно найти применение для более развитых стилей
программирования, чем абстракция данных. Здесь средства, поддерживающие
объектно-ориентированное программирование, очевидно, избыточны.

    Нахождение общности среди отдельных типов системы представляет собой
нетривиальный процесс. Степень такой общности зависит от способа
проектирования системы. В процессе проектирования выявление общности
классов должно быть постоянной целью. Она достигается двумя способами:
либо проектированием специальных классов, используемых как "кирпичи" при
построении других, либо поиском похожих классов для выделения их общей
части в один базовый класс.

    С попытками объяснить, что такое объектно-ориентированное
программирование, не используя конкретных конструкций языков
программирования, можно познакомиться в работах [2] и [6], приведенных в
списке литературы в главе 11.

    Итак, мы указали, какую минимальную поддержку должен обеспечивать язык
программирования для процедурного программирования, для упрятывания
данных, абстракции данных и объектно-ориентированного программирования.
Теперь несколько подробнее опишем средства языка, хотя и не самые
существенные, но позволяющие более эффективно реализовать абстракцию
данных и объектно-ориентированное программирование.

 
« Предыдущая статья   Следующая статья »