Показаны различия между двумя версиями страницы.
bb:redbook:210 [2019/07/24 10:20] caufman [4. Ограниченные типы] |
bb:redbook:210 [2020/10/29 07:08] |
||
---|---|---|---|
Строка 1: | Строка 1: | ||
- | ===== 2.10 Введение в атрибуты типов ===== | ||
- | ==== 1. Понятие о атрибутах типов ==== | ||
- | В каком-то смысле, | ||
- | |||
- | |||
- | ==== 2. Абстрактные типы ==== | ||
- | Абстрактные типы не могут иметь экземпляров. Казалось бы, парадокс: | ||
- | MODULE Test_abstract; | ||
- | | ||
- | TYPE | ||
- | tVector = ABSTRACT RECORD | ||
- | x: REAL; | ||
- | y: REAL; | ||
- | END; | ||
- | | ||
- | VAR | ||
- | v: tVector; | ||
- | | ||
- | BEGIN | ||
- | END Test_abstract. | ||
- | Компилятор прозрачно намекает, | ||
- | MODULE Test_abstract; | ||
- | | ||
- | TYPE | ||
- | tVector = ABSTRACT RECORD | ||
- | x: REAL; | ||
- | y: REAL; | ||
- | END; | ||
- | | ||
- | tMyVector1 = RECORD (tVector) | ||
- | z: REAL; | ||
- | END; | ||
- | | ||
- | tMyVector2 = RECORD (tVector) | ||
- | v: REAL; | ||
- | END; | ||
- | | ||
- | VAR | ||
- | v: tMyVector1; | ||
- | v1: tMyVector2; | ||
- | | ||
- | BEGIN | ||
- | END Test_abstract. | ||
- | Как видно из примера, | ||
- | |||
- | Теперь, | ||
- | |||
- | |||
- | ==== 3. Расширяемые типы ==== | ||
- | Расширяемые типы чем-то похожи на абстрактные. Отличие состоит в том, что тип, описанный как расширяемый, | ||
- | MODULE Test_extensible; | ||
- | | ||
- | TYPE | ||
- | tVector = EXTENSIBLE RECORD | ||
- | x: REAL; | ||
- | y: REAL; | ||
- | END; | ||
- | | ||
- | tMyVector1 = RECORD (tVector) | ||
- | z: REAL; | ||
- | END; | ||
- | | ||
- | VAR | ||
- | v: tVector; | ||
- | v1: tMyVector1; | ||
- | | ||
- | BEGIN | ||
- | END Test_extensible. | ||
- | Абстрактный тип, также может расширяться в типах-потомках, | ||
- | |||
- | |||
- | ==== 4. Ограниченные типы ==== | ||
- | Ограниченные типы не ограничены ни в чём, кроме того, где могут быть созданы экземпляры таких типов. А именно: | ||
- | |||
- | Пример приводится ниже: | ||
- | MODULE Test_limited; | ||
- | | ||
- | TYPE | ||
- | tVector = LIMITED RECORD | ||
- | x: REAL; | ||
- | y: REAL; | ||
- | END; | ||
- | | ||
- | tMyVector1 = RECORD (tVector) | ||
- | z: REAL; | ||
- | END; | ||
- | | ||
- | VAR | ||
- | v: tVector; | ||
- | v1: tMyVector1; | ||
- | | ||
- | BEGIN | ||
- | END Test_limited. | ||
- | Как видно в примере, | ||
- | |||
- | Исправленный пример ниже: | ||
- | MODULE Test_limited; | ||
- | | ||
- | TYPE | ||
- | tVector = LIMITED RECORD | ||
- | x: REAL; | ||
- | y: REAL; | ||
- | END; | ||
- | | ||
- | tMyVector1 = LIMITED RECORD (tVector) | ||
- | z: REAL; | ||
- | END; | ||
- | | ||
- | VAR | ||
- | v: tVector; | ||
- | v1: tMyVector1; | ||
- | | ||
- | BEGIN | ||
- | END Test_limited. | ||
- | И как видно, никаких вопросов у компилятора к программисту не возникает. [↑] | ||
- | |||
- | |||
- | ==== 5. Указательные типы ==== | ||
- | Указательные типы очень часто встречаются в программном коде. Они представляют из себя ссылку на какой-либо тип. Ссылка, | ||
- | |||
- | Частое использование указательных типов вызвано эффективностью работы таких программ. Вместо передачи в процедуру всех полей структуры, | ||
- | - Компилятор не создаёт сам экземпляр указательного типа, экземпляр нужно создавать руками с помощью оператора NEW. Природа указательного типа — динамическая. | ||
- | - Компонентный Паскаль обеспечивает начальную инициализацию полей и массивов для указательных типов. В частности, | ||
- | - При работе с записевыми типами не надо разыменовывать указатели (получать реальное значение переменной по указанному адресу). Компонентный Паскаль прекрасно с этим справляется сам, на основе информации о типе. | ||
- | |||
- | Примеры работы с записевыми типами не сильно отличаются от простых типов: | ||
- | |||
- | |||
- | В результате выполнения указанного фрагмента будут созданы базовый абстрактный тип tVector, который нельзя реализовать непосредственно. На его базе создаётся указательный тип tpVector, который вполне себе реализуем. При начале работе модуля через NEW создаётся экземпляр указательного типа tpVector, а в экспортируемой процедуре Start выводится значение всех полей. Как видно из вывода, | ||
- | |||
- | Также следует отметить, | ||
- | |||
- | |||
- | Как видно из примера, | ||
- | |||
- | PROCEDURE (VAR self: tpVector)Log(), | ||
- | |||
- | использована форма | ||
- | |||
- | PROCEDURE (self: tpVector)Log(), | ||
- | |||
- | Отсутствие ключевого слова VAR (variable — " | ||
- | |||
- | Также необходимо указать на ещё один момент. В секции импорта указан модуль Log. В модуле также есть процедура с таким именем. Но компилятор считает такое смешение имён допустимым. А всё потому, | ||
- | [↑] | ||
- | |||
- | |||
- | ==== 6. Выводы ==== | ||
- | Изложенных данных всё ещё недостаточно для полноценного написания программ в духе ООП. Но полученной инофрмации уже достаточно для написания эффективных и безопасных фрагментов. В конце этой части будет представлена программа, | ||
- | |||
- | [ ← Назад |