Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Когда правила типов становятся несносными

Попытка присваивания

И снова неограниченная универсальность

Игра в рекурсию

 

Вот некий трюк с нашим примером: спросим себя, возможен ли вектор векторов? Допустим ли тип VECTOR [VECTOR [INTEGER]]?

Ответ следует из предыдущих правил: только если фактический родовой параметр совместим с NUMERIC. Сделать это просто - породить класс VECTOR от класса NUMERIC (см. упражнение 16.2):

 

indexing

description: "Векторы, допускающие сложение"

class

VECTOR [G -> NUMERIC]

inherit

NUMERIC

... Остальное - как и раньше...

 

 

Векторы, подобные этому, можно и впрямь считать "числовыми". Операции сложение и умножение дают структуру кольца, в котором роль нуля (zero) играет вектор из G -нулей, и роль единицы (unity) - вектор из G -единиц. Операция сложения в этом кольце - это, строго говоря, векторный вариант infix "+", речь о котором шла выше.

Можно пойти дальше и использовать VECTOR [VECTOR [VECTOR [INTEGER]]] и так далее - приятное рекурсивное приложение ограниченной универсальности.

 

 

Конечно же, не все случаи универсальности ограничены. Форма - STACK [G] или ARRAY [G] - по-прежнему существует и называется неограниченной универсальностью. Пример DICTIONARY [G, H -> HASHABLE] показывает, что класс одновременно может иметь как ограниченные, так и неограниченные родовые параметры.

Изучение ограниченной универсальности дает шанс лучше понять неограниченный случай. Вы, конечно же, вывели правило, по которому class C [G] следует понимать как class C [G -> ANY]. Поэтому если G - неограниченный типовой параметр (например, класса STACK), а x - сущность, имеющая тип G, то мы точно знаем, что можем делать с сущностью x: читать и присваивать значения, сравнивать (=, /=), передавать как параметр и применять в универсальных операциях clone, equal и прочее.

 

 

 

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

 

 

Цель правил типов, введенных вместе с наследованием, в достижении статически проверяемого динамического поведения, так чтобы система, прошедшая проверку при компиляции, не выполняла неадекватных операций над объектами во время выполнения.

Вот два основных правила, представленных в первой лекции о наследовании (лекция 14).

[x]. Правило Вызова Компонентов: запись x.f осмысленна лишь тогда, когда базовый класс x содержит и экспортирует компонент f.

[x]. Правило Совместимости Типов: при передаче a как аргумента или при присваивании его некой сущности необходимо, чтобы тип a был совместим с ожидаемым, то есть основан на классе, порожденным от класса сущности.

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

Правило Совместимости Типов требует больше внимания. Оно предполагает наличие у нас всей информации о типах объектов, с которыми мы работаем. Как правило, это так, - создав объекты, мы знаем, чем они являются, но иногда информация может частично отсутствовать. Вот два таких случая.

[x]. В полиморфной структуре данных мы располагаем лишь информацией, общей для всех объектов структуры; однако нам может понадобиться и специфическая информация, применимая только к отдельному объекту.

[x]. Если объект приходит из внешнего мира - файл или по сети - мы обычно не можем доверять тому, что он принадлежит определенному типу.

Давайте займемся исследованием примеров этих двух случаев. Рассмотрим для начала полиморфную структуру данных, такую как список геометрических фигур:

 

figlist: LIST [FIGURE]

 

 

В предыдущих лекциях рассматривалась иерархия наследования фигур. Пусть нам необходимо найти самую длинную диагональ среди всех прямоугольников списка (и вернуть -1, если прямоугольников нет). Сделать это непросто. Выражение item (i).diagonal, где item (i) - i -й элемент списка, идет вразрез с правилом вызова компонентов: item (i) имеет тип FIGURE, а этот класс, в отличие от его потомка RECTANGLE, не содержит в своем составе компонента diagonal. Решение, используемое до сих пор, изменяло определение класса, - в нем появлялся атрибут, задающий тип фигуры. Однако это решение не столь элегантно, как нам хотелось бы.

Теперь пример второго рассматриваемого случая. Пусть имеется механизм хранения объектов в файле или передачи их по сети, аналогичный универсальному классу STORABLE, описанному нами ранее. Для получения объекта используем:

 

my_last_book: BOOK

...

my_last_book:= retrieved (my_book_file)

 

 

Значение, возвращаемое retrieved, имеет тип STORABLE библиотеки Kernel, хотя с тем же успехом оно может иметь тип ANY. Но мы не ожидали STORABLE или ANY, - мы надеялись получить именно BOOK. Присваивание my_last_book нарушает правило Совместимости Типов.

Даже если написать собственную функцию retrieved, учитывающую специфику приложения и объявленную с подходящим типом, вам не удастся полностью на нее положиться. В отличие от объектов вашего ПО, в котором согласованность типов гарантируется действующими правилами, данный объект к вам поступает со стороны. При его получении вы могли ошибиться в выборе имени файла и прочитать объект EMPLOYEE вместо объекта BOOK, файл мог быть подделан, а при сетевом доступе данные могли быть искажены при передаче.

 

<== предыдущая лекция | следующая лекция ==>
Ограничение родового параметра | Механизм решения
Поделиться с друзьями:


Дата добавления: 2014-01-07; Просмотров: 243; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.011 сек.