Бьерн Страуструп - Абстракция данных в языке С++ - Абстракция данных
ОГЛАВЛЕНИЕ
Абстракция данных
"Абстракция данных" - популярная и в общем неверно определяемая техника
программирования. Фундаментальная идея состоит в разделении несущественных
деталей реализации подпрограммы и характеристик существенных для для
корректного ее использования.
Такое разделение может быть выражено через специальный "интерфейс",
сосредотачивающий описание всех возможных применений программы.
Типичный пример такого интерфейса :
- множество функций, которые могут иметь доступ к структурам
данных, посредством которых представлена "абстракция".
Одна из причин неполноты общепринятого определения состоит в том, что
любая языковая конструкция, поддерживающая абстракцию данных будет выражать
только некоторые аспекты фундаментальной идеи при недостаточности
выражения других. Например:
1. Упрятывание интерфейсов - Возможность спецификации интерфейсов,
препятствующих искажению данных и освобождающих пользователя от
необходимости знать детали реализации.
2. Конструирование интерфейсов - Возможность спецификации
интерфейсов, поддерживающих и навязывающих определенные соглашения
по использованию абстракций.
Примеры включают перегрузку знаков операций и динамическую типизацию.
3. Конкретизация - Возможность создания и инициализации
одного или более "экземпляров" (переменных объектов копий версий)
одной абстракции.
4. Локализация - Возможность упрощения реализации абстракции, принимая
во внимание, что весь доступ к ней направляется через ее интерфейс.
Примеры включают упрощение правил видимости и соглашений по вызову внутри
реализации.
5. Программная среда - Возможность поддержки разработки программм,
использующих абстракции. Примеры включают : загрузчики, понимающие
абстракции; библиотеки абстракций; отладчики, позволяющие программисту
работать в терминах абстракции.
6 Эффективность - Некоторая конструкция языка должна быть
"достаточна эффективна" для того, чтобы быть полезной.
Предполагаемая сфера применения - важный фактор для определения,
какие конструкции должны быть представлен в языке. Напротив,
эффективность конструкций определяет насколько свободно они
могут использоваться в данной программею Эффективность должна
рассматриваться в трех разных контекстах : при компиляции,
связывании и выполнении.
Основной упор при проектировании возможностей абстракции данных в С
делался на 2 и 3 аспектах, то есть на тех возможностях, которые позволяют
программисту обеспечивать элегантные и эффективные интерфейсы к абстракции.
С абстракция данных поддерживает возможность для программиста определять
новые типы, называемые "классами". Члены класса доступны только функциям
из явно объявленного набора. Просто упрятывание информации может быть
достигнуто, например, так :
class data_type
{ // описание данных
/* список функций, которые могут
использовать описания данных
("дружественные" функции) */
};
где только "дружественные функции (*1) могут иметь доступ к переменным
класса d a t a _ t y p e в том виде как они определены в описании данных.
В качестве альтернативы и часто более элегантно можно определить тип
данных, в котором множество функций, имеющих доступ к переменным класса,
само является составной частью самого типа:
class object_type {
/* описания, используемые
для реализации object_type */
public:
/* описания, специфицирующие
интерфейс с object_type */
};
Одна очевидная не нетривиальная цель многих современных проектов
языков программирования состоит в том, чтобы дать возможность
пользователю определять "абстрактные типы данных" с характеристиками
подобным характеристикам фундаментальных типов данных языка.
Ниже мы покажем, как добавляется тип данных c o m p l e x в язык С
и при этом к комплексным переменным могут применяться обычные
арифметические операции. Например :
complex a, x, y, z;
a = x/y + 3*z;
Идея представления объекта черным ящиком в дальнейшем поддерживается
механизмом иерархического конструирования классов из других классов.
Например:
class shape { ... };
class circle : shape { ... };
Класс shape в добавление к тому, что он используется как класс shape
может быть использован просто как circle. Говорят что класс circle есть
производный класс (*2) с классом shape в качестве своего базового класса.
Имеется возможность отсрочить разрешение типа объектов, имеющих общие
базовые классы до времени выполнения. Это позволяет манипулировать
объектами разных типов некоторым общим образом.