Показаны различия между двумя версиями страницы.
Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия | ||
bb:redbook:210 [2018/11/30 01:13] 127.0.0.1 внешнее изменение |
bb:redbook:210 [2020/10/29 07:08] (текущий) |
||
---|---|---|---|
Строка 7: | Строка 7: | ||
==== 2. Абстрактные типы ==== | ==== 2. Абстрактные типы ==== | ||
Абстрактные типы не могут иметь экземпляров. Казалось бы, парадокс: | Абстрактные типы не могут иметь экземпляров. Казалось бы, парадокс: | ||
- | + | MODULE Test_abstract; | |
- | + | ||
+ | TYPE | ||
+ | tVector = ABSTRACT RECORD | ||
+ | x: REAL; | ||
+ | y: REAL; | ||
+ | END; | ||
+ | |||
+ | VAR | ||
+ | v: tVector; | ||
+ | |||
+ | BEGIN | ||
+ | END Test_abstract. | ||
Компилятор прозрачно намекает, | Компилятор прозрачно намекает, | ||
- | + | MODULE Test_abstract; | |
- | + | ||
- | + | | |
+ | 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. | ||
Как видно из примера, | Как видно из примера, | ||
Строка 20: | Строка 50: | ||
==== 3. Расширяемые типы ==== | ==== 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. | ||
Абстрактный тип, также может расширяться в типах-потомках, | Абстрактный тип, также может расширяться в типах-потомках, | ||
Строка 29: | Строка 75: | ||
Пример приводится ниже: | Пример приводится ниже: | ||
- | + | MODULE Test_limited; | |
- | + | ||
- | + | | |
+ | 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. | ||
И как видно, никаких вопросов у компилятора к программисту не возникает. [↑] | И как видно, никаких вопросов у компилятора к программисту не возникает. [↑] | ||
Строка 49: | Строка 126: | ||
Примеры работы с записевыми типами не сильно отличаются от простых типов: | Примеры работы с записевыми типами не сильно отличаются от простых типов: | ||
- | + | MODULE Test_pointer; | |
- | + | ||
+ | IMPORT Log; | ||
+ | |||
+ | TYPE | ||
+ | tVector = ABSTRACT RECORD | ||
+ | x: REAL; | ||
+ | y: REAL; | ||
+ | END; | ||
+ | |||
+ | tPVector = POINTER TO RECORD (tVector) | ||
+ | z: REAL; | ||
+ | END; | ||
+ | |||
+ | VAR | ||
+ | v: tPVector; | ||
+ | |||
+ | PROCEDURE Start*; | ||
+ | BEGIN | ||
+ | Log.Real(v.x); | ||
+ | Log.Ln | ||
+ | END Start; | ||
+ | |||
+ | BEGIN | ||
+ | NEW (v); | ||
+ | END Test_pointer. | ||
+ | |||
+ | (!)Test_pointer.Start | ||
+ | |||
+ | компилируется " | ||
+ | старый модуль Test_pointer выгружен | ||
+ | 0.0 0.0 0.0 | ||
В результате выполнения указанного фрагмента будут созданы базовый абстрактный тип tVector, который нельзя реализовать непосредственно. На его базе создаётся указательный тип tpVector, который вполне себе реализуем. При начале работе модуля через NEW создаётся экземпляр указательного типа tpVector, а в экспортируемой процедуре Start выводится значение всех полей. Как видно из вывода, | В результате выполнения указанного фрагмента будут созданы базовый абстрактный тип tVector, который нельзя реализовать непосредственно. На его базе создаётся указательный тип tpVector, который вполне себе реализуем. При начале работе модуля через NEW создаётся экземпляр указательного типа tpVector, а в экспортируемой процедуре Start выводится значение всех полей. Как видно из вывода, | ||
Также следует отметить, | Также следует отметить, | ||
- | + | MODULE Test_pointer; | |
- | + | ||
+ | IMPORT Log; | ||
+ | |||
+ | TYPE | ||
+ | tPVector = POINTER TO RECORD | ||
+ | z: REAL; | ||
+ | END; | ||
+ | |||
+ | VAR | ||
+ | v: tPVector; | ||
+ | |||
+ | PROCEDURE (v: tPVector)Log(), | ||
+ | BEGIN | ||
+ | Log.Real(v.z); | ||
+ | END Log; | ||
+ | |||
+ | PROCEDURE Start*; | ||
+ | BEGIN | ||
+ | v.Log | ||
+ | END Start; | ||
+ | |||
+ | BEGIN | ||
+ | NEW (v); | ||
+ | END Test_pointer. | ||
+ | |||
+ | (!)Test_pointer.Start | ||
+ | |||
+ | компилируется " | ||
+ | старый модуль Test_pointer выгружен | ||
+ | 0.0 | ||
Как видно из примера, | Как видно из примера, | ||