Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курс лекций Языки программирования.doc
Скачиваний:
9
Добавлен:
01.04.2025
Размер:
1.42 Mб
Скачать

Глава 5. Инкапсуляция. Абстрактные типы данных (атд).

Инкапсуляция – это скрытие деталей реализации типа данных от доступа извне. Каждый тип данных представляется множеством значений и множеством операций. Инкапсуляция – это скрытие деталей структуры данных, и, возможно, некоторых операций. Скрытые детали реализации доступны только для операций данного типа (закрытый член класса можно использовать только из функций-членов этого класса).

Инкапсуляция нужна, прежде всего, для надежности (например, бесконтрольный доступ к элементам класса Stack – body и top, нарушает целостность структуры данных). Как ни странно, инкапсуляция не усложняет задачу клиента, а довольно часто наоборот упрощает. Она позволяет изолировать внимание программиста, который использует соответствующий класс, от несущественных, с точки зрения использования, деталей.

Модула–2.

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

DEFENITION MODULE M; //Модуль определений

…… //все, что описано в модуле определений

//видно всем.

END M.

IMPLEMENTATION MODULE M; //Модуль реализации

…… //все, что описано в модуле реализации

//не видно никому.

END M.

Для того, чтобы использовать этот модуль в другом модуле, в использующем модуле должно быть объявление IMPORT M. Но объекты из импортируемого модуля доступны только через квалификатор модуля: имя_модуля.имя_объекта. Поскольку модули друг в друга вкладывать нельзя, то хватает одного уровня уточнения (квалификации). Если нам тяжело каждый раз писать квалификатор, то мы можем написать другую форму импортирования: FROM имя_модуля IMPOPT список_имен_объектов. После этого, квалификатор можно не писать, но за это приходится выписывать все используемые объекты вначале программы.

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

Delphi.

В языке Turbo Pascal и в Delphi все несколько проще. Импорт производится так: uses имена_модулей. Имена объектов из этих модулей можно использовать без квалификатора. При конфликте имен приоритет отдается локальному имени по отношению к импортируемому. Квалификатор нужен только тогда, когда возникает конфликт импортируемых имен.

Какой подход удобнее – более жесткий подход Модулы-2, или языка Turbo Pascal? На первый взгляд, подход Turbo Pascal удобнее, но когда приходится разбираться в больших программах, то при таком подходе нередко приходится смотреть реализацию исходников библиотек. Представьте, что вам встретилась некая переменная DelayFactor. Что она означает? Вы ищете в Help, и естественно ничего не находите. Как узнать к какому модулю она принадлежит, если в эту программу импортируется десяток модулей? Не случайно есть утилита grep, которая позволяет искать строку в заданном наборе файлов – это совершенно необходимая вещь. В Модуле-2 наличие квалификаторов в таких случаях очень помогает – сразу видно, к какому модулю принадлежит объект, а если квалификатора нет, то это можно посмотреть в заголовке IMPORT.

Т.е. программу на Модуле-2 гораздо удобнее читать. Кто важнее – читатель или писатель? Настоящий программист должен быть и тем и другим, тем более, что после серьезной работы над программным проектом, программист из писателя наполовину превращается в читателя.