лекции (2004) (1160823), страница 17

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

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

1. сложная семантика свойств не видна для пользователя

2. в случае интеграции компонент (сред программирования)

Свойства есть в языках Дельфи и Cи#.

  • Дельфи

В Дельфи обычный член выражается

имя: тип;

Свойство выражается:

property

имя: тип;

read считыватель; // может быть имя другого члена-данного, либо имя функции-члена

function rd:тип

write писатель; // может быть имя другого члена-данного, либо имя процедуры-члена

procedure wr(value:тип);

После этого всего может стоять слово default (о свойствах по умолчанию позже).

Функция считыватель - возвращает значение. Функция писатель - записывает. Зачем вводить дополнительные члены?

  1. пусть у нас есть:

m_I:integer;

  1. мы вводим свойство:

property i:integer;

read m_i;

write m_i;

Если какой-нибудь смысл в таком объявлении? В таком коде особого смысла нет. Но надо иметь ввиду, что либо писать, либо читатель может быть опущен. Тогда мы можем, например, m_I закрыть на запись и открыть на чтение, и такой подход (использование свойств) очень удобен.

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

RECORD

X*-:INTEGER; //Х – является вообще-то публичным членом записи, но доступен только на чтение, но не на запись

В Си++ механизма свойств нет, и никто не спешит его вводить, так как пара функций get() и set() вполне решает проблему. Но в других языках, например в Обероне, необходим специальный механизм позволяющий закрывать переменную на запись. Почему так происходит? Обычно, значение переменной используется часто, если мы используем функцию типа get() она соответственно будет вызываться очень часто. Эта функция в простейшем случае возвращает закрытую или приватную переменную. В архитектуре современных процессоров большую роль играет процесс конвейеризации, когда мы спараллеливаем выполнение многих операций. Отметим, что сейчас повышение быстродействия процессора происходит не за счет увеличения гигагерц, а в результате усовершенствования их внутренней структуры и распараллеливания операций. Любой вызов функции, как и любой нелокальный переход, полностью гробит весь конвейер. В языке Си++ это решается при помощи inline-функций. Так если функция описана внутри класса, то она по умолчанию считается inline. inline - это указание компилятору, что вызов функции можно заменить ее телом, и никаких накладных расходов не будет. В Обероне это понятие отсутствует, поэтому ввели специальное решение для частной проблемы.

Свойства по умолчанию:

Если после свойства стоит ключевое слово default, то это означает, что в случае, если мы не знаем какое свойство на нужно, то компилятор подставляет это свойство. Что означает – мы не знаем, какое свойство нам нужно? Рассмотрим ситуацию:

class X

property I:T,

read … //в данный момент нас конкретные считыватели и писатели не интересуют

write…//в данный момент нас конкретные считыватели и писатели не интересуют

default;

end;

пусть у нас

Х а;

Т j;

а := Х.create();

j := a; // у нас переменные разных типов данных, отметим что в таком контексте нам от Х требуются данные типа Т. Вообще-то в такой ситуации компилятор дожжен ругаться на несоответствие типов данных. Но данном случае, если Х является классом, и у класса Х есть свойства типа Т, и это свойство является свойством по умолчанию, все это приводит к тому, что компилятор вставляет следующий код:

j := a.i; // получается, что тип данных слева и справа

один и тот же – Т

Это похоже на то, что мы рассматривали ранее j := (T)a. Это очень похоже на неявные преобразования. Таким образом, создатели языка Дельфи предусмотрели возможность неявных преобразований. Из класса Х всегда можно преобразовать в другой класс У, если в соответствующем классе опишем свойство типа У по умолчанию. Чаще всего такой механизм неявных свойств используется, если, например, компонента содержит в себе какой-либо контейнер, то имеет смысл делать этот контейнер свойством по умолчанию. Так класс одновременно проявляет черты некоторого контейнера, но и еще какие-то дополнительные черты. Хотя еще раз отметим: мы стоим на позиции, что никаких неявных преобразований в Дельфи нет.

Вопрос о перекрытии стандартных операций. Во все языках (кроме Оберона) есть перекрытие имён (одному и тому же имени соответствует несколько объектов). Компилятор различает эти объекты из контекста.

5)Перекрытие операций(формально не является свойством класса)

Перекрытие имен – overload (не путать с заменой), это означает, что одному имени соответствует несколько объектов в одной и той же области видимости. Решение о связывании имени с конкретным объектом всегда принимает компилятор исходя из контекста, связывание всегда статическое. В рассматриваемых нами языках понятие перекрытия есть (кроме Оберона), оно относится только к именам подпрограмм. Если речь идет об имени типа, переменной, константы – то правило: в одной области видимости одному имени – одна сущность.

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

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

  • Для языков, основанных на понятии выражения (Си++), это только сам вызов функции ничего более (имя и параметры).

Стандартные операции выглядят так: operator(arg1, arg2);

Для операции + : operator +(arg1, arg2); или operator +(arg1);

То же самое и для Дельфи, и для Си#, и для Java. Как следствие, перекрытие происходит по числу и типу параметров. В языке Дельфи при перекрытии операции после объявлении процедуры мы должны указывать ключевое слово overload.

  • Более интересная ситуация в языке Ада. Используется перекрытие к именам литералов перечисления:

type T1 is (a, b, c);

T2 is (b, c, d); // это допустимо

Можно считать, что в такой ситуации речь идет о функциях, поскольку любую константу можно считать нульместной функцией, т.е. функцией без аргументов, которая возвращает фиксированное значение. В отличии от Си++, Си#, Java, где вызов функции сопровождается круглыми скобками, в Аде функцию или процедуру без параметров можно вызывать просто указывая ее имя.

В Аде понятие контекста вызова подпрограммы глубже. Контекстом вызова процедуры является сам оператор вызова процедуры, а контекстом вызова функции – выражение, внутри которого она вызывается.

  1. z:= T1!b;// трактуй b как Т1

2)z:= c;// контекстом является вся конструкция, а именно оператор присваивания

так как c принадлежит и к Т1, и к Т2, то его тип в данном присваивании зависит от типа z

3)if f() then - здесь требуется функция, возвращающая логическое значение

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

А нельзя ли сделать пользовательскую семантику для стандартных операций? Здесь существуют две идеологии:

1) Да, это можно - идеология Ада, Cи#, Си++.

2) Нет, это нельзя - идеология Java, Дельфи

Все языки, которые мы рассматриваем, соблюдают ограничение на количество аргументов – сколько аргументов есть у стандартной операции, столько же должно быть у перекрытой. Это сделано для того, чтобы не менялся алгоритм синтаксического анализа (есть языки, которые как правило не компилируют, не поддерживающие это правило - PROLOG ).

Рассмотрим синтаксис:

Ада

function "+"

(X.T) return T;

(X1, X2:T) return T;

Заметим, что ни одном языке, который мы рассматриваем, нет ограничения на типы аргументов и на тип возвращаемого значения. Это может быть нехорошо, если в Си++ мы перекроем операцию присваивания как void- функцию. И тогда a=b=c; // ERROR

Можно еще сделать так: У& operator = (X&); когда надо сделать бы: X& operator = (X&). Кроме того плохим тоном считается придание перекрытиям специфического значения, т.е. операция сложения должна складывать, а не вычислять квадратный корень. Аналогично при перекрытии оператор "->" (ссылка на объект), он не должен, например, складывать свои аргументы.

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

Обратите внимание:

Любой класс является типом данных (но не наоборот - для Си++, а для Си# - для любого тд есть класс из стандартной библиотеки). Есть понятие абстрактный класс и есть абстрактный тип данных. Но абстрактный класс - совсем не то, что абстрактный типа данных! Абстрактный класс (вот, например, для Си++ абстрактный класс – такой, у которого есть хотя бы одна виртуальная функция) имеет отношение к наследованию и к механизму динамического связывания. А абстрактный тип данных имеет отношение только к механизму инкапсуляции.

Сейчас мы поговорим об инкапсуляции. Инкапсуляция - упрятывание. Что можно упрятать и зачем это делать? Вспомним, что тип данных = множество значений + множество операций. Можно упрятывать структуры данных (целиком или по частям), плюс, как следствие, операции, которые есть процедуры или функции, привязанные к определенному тд. Пользователь не должен знать множество значений и то, как реализованы операции (тела соответствующих процедур и функций). У нас есть специальные конструкции – модули или классы, которые связывают воедино структуру данных и соответствующее множество операций. До этого не осуждалось, ограничен или нет доступ к членам модуля или класса. Об инкапсуляции речь зашла, когда разбирались модульные языки – разделение на модуль определений и модуль реализации для Модула 2 (либо на интерфейсную и реализационную части юнита в Дельфи, либо в спецификация и тело пакета в Аде). Вспомним, что все имена описанные в реализационной части упрятаны, так как они доступны только внутри модуля реализации.

Есть еще дополнительные возможности упрятывания. Абстрактным типом данных называется тип данных, множество значений которого упрятано от программиста. Работа с ним возможна только в терминах явно определенного множества операций (add() и т.п.). Можно сказать, что АТД – это множество операций, определенное явно.

Рассмотрим, как реализована инкапсуляция и АТД в разных ЯП, увидим, что наиболее полно все это реализовано в Аде. Кроме того, понятие инкапсуляции надо рассматривать отдельно применительно к модулям, и отдельно применительно к классам.

  1. Единица защиты

Единицей защиты может быть тип целиком, либо член типа (часть типа). Модульные языки (Ада, Модула-2) ориентированы на то, что единица защиты - тип целиком (тип либо полностью открыт, либо полностью закрыт).

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

Итак, ограничение на весь тип, программирование в терминах АТД – это особенности языка Ада (и модульных яп). В современных яп допускается оператор goto, и наличие классов определяет несколько иную тенденцию: единицей защиты является член типа, а именно член-данное. Если мы вспомним внеклассовый язык Оберон – там ситуация такая же, запись может быть целиком закрытая, частично открытая. Подразумевается, что лучше по возможности goto не использовать и программировать в терминах АТД.

  1. Атом защиты

Атом защиты - весь тип и отдельные экземпляры. Атомом защиты всегда является весь тип. Нельзя сказать, что для данного экземпляра это поле является открытым, а для остальных закрытым, т.е. для всех экземпляров типа единообразны правила видимости или доступа.

  1. Видимость или доступ

В чем тут различия. В языках, где ограничения на правила доступа, там видимыми являются все члены, но не ко всем членам разрешен доступ. Инкапсуляция выглядит так: видимыми с точки зрения компилятора и программиста являются все имена описанные, например, в классе. Все языки, в которых есть понятие класса, ориентированы на доступ. А модульные языки ориентированы на видимость. Разница между видимость и доступом проявляется именно при наследовании, а если наследования нет, то видимость и доступ эквивалентны.

Каким образом реализуется упрятывание в модульных ЯП: вся реализация – упрятана, всё, что в интерфейсе - всё открыто (Дельфи, Модула-2).

Небольшие отличия в языке Ада:

package P is

type T1 is array(1..N) of Real; // это целиком открытый тд

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

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

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

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