Главная » Просмотр файлов » лекции (1998) (Буров)

лекции (1998) (Буров) (1161123), страница 17

Файл №1161123 лекции (1998) (Буров) (лекции (1998) (Буров)) 17 страницалекции (1998) (Буров) (1161123) страница 172019-09-19СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 17)

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 гораздо удобнее читать. Кто важнее – читатель или писатель? Настоящий программист должен быть и тем и другим, тем более, что после серьезной работы над программным проектом, программист из писателя наполовину превращается в читателя.

Оберон.

Оберон – значительно более простой язык, чем Модула-2. В Обероне подход совсем жесткий: есть конструкция IMPORT список_имен_модулей. Программист всегда обязан обращаться к объектам через квалификатор: имя_модуля.имя_объекта. Конечно, писать приходится много (хотя можно использовать копирование), но зато читать совсем удобно.

Итак, в Обероне и Модуле-2 можно отметить следующие общие моменты:

  1. Простота модульной структуры. Все модули вытягиваются в цепочку. Логически, конечно, у них есть некоторая иерархия (дерево), которая определяется отношением импорта, но взаимоотношения между модулями очень просты.

  2. Инкапсуляция является наиболее простой – все что видно в модуле определений, то является общедоступным (через квалификатор). Но в Модуле-2 мы не можем скрыть часть структуры, скрыть можно только целую сущность. {* Оберон рассматривается на следующей лекции *}

Лекция 14

Инициализация статических членов в Java (отступление)

Когда мы говорили о языке Java, то забыли рассмотреть один момент, а именно – Инициализацию статических членов.

Статические члены (как функции, так и данные) играют роль глобальных функций и переменных, однако, не обладающие их недостатками. Язык Java вообще не принимает концепцию глобальных объектов – их роль играют статические члены.

Коль скоро статические члены в Java используются достаточно интенсивно, встает вопрос об их инициализации. В C++ этот вопрос практически не решен (нет механизмов). Проблема заключается в том, что статические объекты должны инициализироваться до входа в функцию main().

В Java этот вопрос решается, например, таким образом:

class X {

static i=10;

int j=1;

… }

Понятно, что код “static i=10” будет сгенерирован внутри конструктора, то есть компилятор генерирует конструктор таким образом, что в начале выполняется инициализация базового класса, потом инициализация, указанная в классе, а уж затем – тело конструктора. В случае, если у нас есть инициализация статических членов, то компилятор вставляет это в стандартный пролог, который выполняется перед выполнением функции main() соответствующего апплета.

Всегда возникает ситуация менее тривиальной инициализации, например:

static int[ ] arz = new int [10];

Но, вообще говоря, члены этого массива могут инициализироваться и по более хитрому правилу (например, им может быть присвоена совокупность 10 случайных чисел). Создатели Java подошли к этому вопросу серьезно, они разрешили создание статических блоков:

static { … };

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

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

Pascal, Oberon, Modula-2, Ada, Delphi.

Когда мы говорили о модулях в таких языках, как Pascal, Oberon, Modula-2, то упоминали про инициализирующую часть, например, в Ada:

package body P is

begin

<инициализация>

end

- инициализация выполняется один раз при загрузке пакета. Так как пакет загружается статически, то инициализация находится в прологе программы.

Точно такая же возможность есть в модулях Modula-2 и Delphi. В последнем даже возможно делать так:

initialization

finalization

end имя_unit

На этом мы завершим разговор об инициализации статических членов и вернемся к уже начатой теме инкапсуляции и абстрактных типов данных.

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

Modula-2

Мы говорили о том, что в Modula-2 инкапсулируются (скрываются от доступа извне) только данные и операции, находящиеся внутри модуля реализации. В случае же, если мы напишем:

DEFENITION MODULE M;

TYPE T=RECORD

END M;

, то у нас нет никакой возможности упрятать детали структуры T. Где же тогда инкапсуляция? В данном случае ее нет, так как единицей защиты служит целый тип, мы не можем ограничить доступ к отдельным данным этого типа. Возникает вопрос, а есть ли настоящая инкапсуляция в Modula-2? Есть.

Дело в том, что абстрактный тип данных с точки зрения пользователя выглядит только, как множество операций, структура данных (множество значений) пользователю не видна. Вобщем-то это и есть определение АТД. (Заметим, что АТД и абстрактный класс в C++ немного разные вещи и смешивать их не стоит).

Набор операций, открытый пользователю (любому объекту, использующему данный тип данных), называется интерфейсом АТД. Иначе говоря, доступ к АТД может осуществляться только через определенный интерфейс, никакие детали реализации недоступны.

Как описать такой абстрактный тип данных, например, на Modula-2? Заметим, что Modula-2 предлагает две альтернативы: полностью открыть структуру типа данных, либо полностью ее закрыть. В Modula-2 есть понятие скрытого типа – это тип, объявление которого в модуле определений выглядит, как

TYPE T;

- без структуры. Так как клиенту доступно только то, что описано в модуле определений, то к типу T никакие операции, кроме описанных там же в модуле определений не применимы. (Это не совсем так - кроме описанных операций еще можно использовать “:=”, “=”, “<>” – присваивание, равенство, неравенство.)

На первый взгляд, кажется, у нас появился АТД. Но проблема Modula-2 заключается в том, что в нем слишком жестко реализована раздельная трансляция. Мы будем говорить о ней позже, но сейчас отметим то, что модули реализации и определений должны быть физически разделены друг от друга – они компилируются отдельно. В принципе, можно даже откомпилировать их отдельно, а можно откомпилировать только модули определений и собрать программу, разумеется создать исполняемый файл мы не сможем.

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

Заметим, что Turbo Pascal избрал другой подход: там определения и реализация соединены в одном модуле (Unit), не в последнюю очередь это было сделано из-за того, что Turbo Pascal невероятно быстро компилирует код. Это же унаследовала система Delphi.

О компиляции мы еще будем говорить позже. А сейчас отметим тот факт, что для реализации вышеуказанной схемы разделения модулей необходимо наложение на тип данных. Пусть у нас есть модуль M (в нем определен тип T) и клиентский модуль C.

Module C:

IMPORT M;

VAR X: M.T;

Как компилятор будет распределять память? Что он знает о типе данных T? Ответ: он ничего не знает, кроме имени. Отсюда вытекает, что на данную схему должны быть наложены ограничения, а именно – тип T ( с точки зрения реализации ) может быть либо указателем, либо типом, совместимым по размеру памяти с указателем (например, integer). Отсюда вытекает, что инкапсуляция в Modula-2 заставляет прибегать к реализации типа в динамической памяти. (Есть исключения: например, работа с файлами.)

Например, если у нас есть АТД стек:

DEFENITION module Stacks:

TYPE STACK;

PROCEDURE Init( VAR S: STACK );

PROCEDURE Push( …);

PROCEDURE Pop( … );

PROCEDURE Destroy( … );

END STACK;

Вполне естественно, что разумнее реализовать стек в динамической памяти (отсюда появляются Init и Destroy).

А в модуле реализации будет следующее:

TYPE STACK = POINTER TO StackRec;

StackRec = Record

END;

То есть StackRec – это уже инкапсулированная структура данных. И уже Init будет заниматься распределением правильного количества памяти (Destroy ее освобождать) – эти процедуры являются аналогами конструктора и деструктора, правда, с одним отличием – мы сами должны не забыть вызывать в нужных местах Init и Destroy. Никакого контроля нет.

В итоге мы имеем два недостатка:

  • невозможность защитить отдельные поля типа данных, только весь тип целиком

  • навязывается конкретный способ реализации АТД (программист, который не хотел использовать динамические структуры данных не мог воспользоваться преимуществами инкапсуляции)

Oberon

Интересно то, что Oberon, который является более простым языком, чем Modula-2, убирает оба этих недостатка. В нем соединены понятия модуля реализации и модуля определений в одном физическом модуле.

MODULE

TYPE Stack* = RECORD

body: array 50 of INTEGER;

top: INTEGER;

END;

При этом можно открывать из закрывать отдельные поля типа (с помощью указания “*”). В данном примере мы не экспортируем внутреннюю часть типа (body и top), а только имя типа. В модуле определений (заметим, что это не часть языка, а лишь документационная часть для справки программисту), который будет сгенерирован мы увидим:

TYPE Stack = RECORD END:

Также и для процедур/функций – указание «*» будет означать экспорт.

В Oberon применяется очень простое математическое понятие проекции: все, что мы пометим «*» будет являться проекцией оригинала в модуль определений. Более того в Oberon-2 появилось понятие переменной, доступной только на чтение:

VAR Done *-: BOOLEAN;

То есть мы не сможем изменить переменную Done (это удобно для информационных переменных, которые содержат, например, коды ошибок).

Очевидно, что при изменении модуля реализации нам придется перекомпилировать клентские модули. Но, надо отметить, что здесь можно воспользоваться некоторыми хитростями уже в реализации.

С точки зрения модели видимости оба языка используют один и тот же механизм. В них есть два вида видимости:

  • потенциальная видимость (имена, которые доступны через квалификатор или уточнение, например, имена объектов из интерфейсной части модуля)

  • непосредственная видимость (имена, которые можно употреблять без уточнений, имена библиотек модулей)

В Modula-2 потенциальная видимость может быть снята следующим образом:

FROM M IMPORT …;

Ada

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

package M is

end M;

Характеристики

Тип файла
Документ
Размер
1,12 Mb
Тип материала
Высшее учебное заведение

Список файлов лекций

Свежие статьи
Популярно сейчас
Как Вы думаете, сколько людей до Вас делали точно такое же задание? 99% студентов выполняют точно такие же задания, как и их предшественники год назад. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6274
Авторов
на СтудИзбе
316
Средний доход
с одного платного файла
Обучение Подробнее