есть: Ада
При односторонней связи (импорт-экспорт) модуль, экспортирующий имена, не зависит от импортирующих (клиентских) модулей. При двусторонней связи оба модуля зависят друг от друга. В языке Ада двусторонняя связь используется при раздельной трансляции вложенных модулей.
Вложенный модуль обозначается «заглушкой» во внешнем модуле:
procedure Outer is
–- заглушка
procedure Inner is separate;
...
end Outer;
При трансляции вложенный модуль снабжается заголовком, связывающим его с объемлющим модулем:
separate(Outer)
procedure Inner is
...
end Inner;
Связь «заглушка-заголовок» - пример двусторонней связи.
8. Исключительные ситуации и обработка ошибок
Понятие исключительной ситуации (ИС) и его эволюция. ИС и ошибки
в программах. Четыре аспекта рассмотрения ИС: определение,
возникновение, распространение и обработка. Воплощение этих аспектов в
современных ЯП.
8. Смоделируйте на языке Си++ функции void f() throw (E1,E2,E3) { g(); h(); } предполагая, что конструкция throw не допускается компилятором.
void f()
{
try {
g(); h();
} catch (E1){
throw;
} catch (E2){
throw;
} catch (E3){
throw;
} catch (...) {
unexpected();
}
}
Пример для языка Delphi:
if ptr = nil then
raise Exception.Create('Invalid pointer');
Два подхода к обработке ИС: семантика возобновления и семантика
завершения. Их сравнение. Семантика завершения и современные ЯП.
Семантика возобновления: после обработки исключения управление может вернуться непосредственно в точку, где возникло исключение (варианты: на следующий оператор или на любой оператор из того же блока).
Пример языка: Visual Basic.
Семантика завершения: после возникновения исключения блок, в котором оно возникло, обязательно завершается. Обработка исключения происходит в блоках, вызвавших блок с исключением.
|
Пример языка: Си++.
В языке Си++ реализована другая семантика: завершения, но в некоторых случаях семантика возобновления может быть смоделирована, например, в случае выделения возобновляемого ресурса (типа динамической памяти):
Resource GetResource() {
for (;;)
try {
Resource r = … // попытка получить ресурс, например
// выделить память
if (success) return r;
throw NoResourceException();
} catch (NoResourceException) {
// попытка найти дополнительные ресурсы (например,
// динамически собрать мусор)
if (!success) throw;
}
}
Свертка стека. Оператор try-finally.
Дополнительные особенности ИС: спецификация ИС, проверяемые и
непроверяемые ИС.
9. Наследование типов и классов
Концепция уникальности типов в традиционных языках и строгая
типизация в объектно-ориентированных языках. Понятие единичного
наследования. Единичное наследование в современных ЯП. Наследование и
модель представления объекта в памяти. Преобразование из производного
типа в базовый. Иерархии типов, статические и динамические типы в
объектно-ориентированных ЯП.
У ссылок и указателей появляется понятие динамического типа. (Статический тип определяется при объявлении. Собственно сами объекты данных обладают только статическим типом.) Динамический тип – это тип объекта, на который ссылка или указатель ссылаются в даный момент. Собственно объекты данных свой тип менять не могут.
С++: class Derived: [модификатор] Base {
// обьявление новых членов };
[модификатор]::= {private, public, protected}
по умолчанию приватное. Чаще всего приватное наследование используется в написании интерфейсов. Public – не меняет модификатор доступа свойств наследуемого
|
класса в производном, protected – делает все публичные свойства наследуемого класса защищенными, а private – все свойства наследуемого класса делаем закрытыми (модификатор доступа private).
С#: class Derived: Base {
//определение новых членов }
Java: class Derived extends Base {
// определение новых членов }
Java использует слово extends для выражения единственного типа наследования, соответствующего публичному наследованию в C++. Java не поддерживает множественное наследование. Классы Java тоже происходят от общего базового класса.
Oberon, Object Pascal, Turbo Pascal:
TYPE Derived = RECORD (Base)
// определение новых членов
END;
Delphi:
TYPE Derived = class (Base)
// определение новых членов
END;
В этих языках при наследовании используется не ключевое слово, а специальный синтаксис - добавление в скобках имени базового класса. Эти языки поддерживают только один тип наследования, который в C++ называется публичным.
Ada: type Base is tagged record
// члены end;
Type Derived is new Base with record
// определение новых членов end;
// новые члены не определяются, используется для добавления новых методов к базовому классу
Type Derived is new Base with null record;
package P is
type Base is tagged private;
………………………………………..
Где-то в конце есть спецификация пакета:
private
type Base is tagged record
….............................................
end P;
Где будем наследовать Base?
Если в этом же пакете, то делаем это так:
type Derived is new Base with private
..............................................................
Если это определение в том же модуле, то структура этого Derived должна быть описана в приватной части пакета.
Но если оба типа описываются в одном модуле, и у типа Base есть приватные члены, даже тогда относительно derived у него нет ничего приватного.
|
Защищенных членов в Ада и Оберон нет, таким образом, в этих языках всего два вида доступа:
1) публичный
2) приватный – его по большому счету тоже нет, так как в Ада есть дочений пакет.
package P.P1
Это означает, что фактически определяемое в нем как бы приписывается в конец приватной части в конце пакета.
Замечания:
1.В Java, C#, Delphi каждый класс происходит по крайней мере от некоторого базового класса по умолчанию. Этот класс обладает некоторыми основными способностями, доступными всем классам. Этот подход является общим ещё и потому, что так первоначально делалось в Smalltalk. Также любой класс может стать первым в иерархии классов в таких языках, как Оберон, Ада – 95.
2.Единственный язык, поддерживающий множественное наследование из языков, проходимых в курсе ООП – язык С++.
3. Единственный язык, поддерживающий модификацию прав доступа свойств базового класса в производном – язык С++.
Наследование и области видимости имен. Замещение, перегрузка и
скрытие имен при наследовании. Наследование и инкапсуляция. Управление