Инструменты пользователя

Инструменты сайта


bb:redbook:211

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
bb:redbook:211 [2016/04/05 12:24]
prospero78 [1. Понятие о атрибутах методов]
bb:redbook:211 [2020/10/29 07:08] (текущий)
Строка 14: Строка 14:
  
 Пример ниже демонстрирует некоторые возможности абстрактных методов: Пример ниже демонстрирует некоторые возможности абстрактных методов:
-  +  MODULE Test_abs_method; 
-  +   
- +  IMPORT Log; 
 +   
 +  TYPE 
 +      tVector = POINTER TO ABSTRACT RECORD 
 +          x*: REAL; 
 +      END; 
 +   
 +      tMyVector = POINTER TO RECORD (tVector) 
 +          z*: REAL; 
 +      END; 
 +   
 +      tMyVector1 = POINTER TO RECORD (tVector) 
 +          z*: REAL; 
 +      END; 
 +   
 +  VAR 
 +      v: tMyVector; 
 +      v1: tMyVector1; 
 +   
 +  PROCEDURE (v: tVector)Log*, NEW, ABSTRACT; 
 +   
 +  PROCEDURE (v: tMyVector)Log*(); 
 +  BEGIN 
 +      Log.Real(v.z); Log.Real(v.z); Log.Ln 
 +  END Log; 
 +   
 +  PROCEDURE (v: tMyVector1)Log*(); 
 +  BEGIN 
 +      Log.String("Привет, мир!"); Log.Ln; 
 +      Log.Real(v.z); Log.Real(v.z); Log.Ln; 
 +      Log.String("-------------"); Log.Ln; 
 +  END Log; 
 +   
 +  PROCEDURE Start*; 
 +  BEGIN 
 +      v.Log; 
 +      v1.Log 
 +  END Start; 
 +   
 +  BEGIN 
 +      NEW (v); 
 +      NEW (v1); 
 +  END Test_abs_method. 
 + 
 +  (!)Test_abs_method.Start 
 +   
 +  компилируется "Test_abs_method"   236   8 
 +  старый модуль Test_abs_method выгружен 
 +   0.0 0.0 
 +  Привет, мир! 
 +   0.0 0.0 
 +  -------------
 Как видно из примера, абстрактный метод Log для абстрактного типа tpVector реализуется в типе-потомке tpMyVector и tpMyVector1. Вызовы совершенно одинаковые, а результат работы разный. Для переменной v — это просто значение полей. Для переменной v1 — ещё и какие-то дополнительные надписи. [↑] Как видно из примера, абстрактный метод Log для абстрактного типа tpVector реализуется в типе-потомке tpMyVector и tpMyVector1. Вызовы совершенно одинаковые, а результат работы разный. Для переменной v — это просто значение полей. Для переменной v1 — ещё и какие-то дополнительные надписи. [↑]
   
Строка 30: Строка 81:
 ==== 5. Атрибут EXTENSIBLE ==== ==== 5. Атрибут EXTENSIBLE ====
 Атрибут EXTENSIBLE для методов, также как и для типов, указывает о том, что метод можно переопределять в типах-потомках. Немного переделав предыдущий пример, можно продемонстрировать как это работает: Атрибут EXTENSIBLE для методов, также как и для типов, указывает о том, что метод можно переопределять в типах-потомках. Немного переделав предыдущий пример, можно продемонстрировать как это работает:
-  +  MODULE Test_ext_method; 
- +   
 +  IMPORT Log; 
 +   
 +  TYPE 
 +      tVector = POINTER TO ABSTRACT RECORD 
 +          x*: REAL; 
 +      END; 
 +   
 +      tMyVector = POINTER TO EXTENSIBLE RECORD (tVector) 
 +          y*: REAL; 
 +      END; 
 +   
 +      tMyVector1 = POINTER TO RECORD (tMyVector) 
 +          z*: REAL; 
 +      END; 
 +   
 +  VAR 
 +      v: tMyVector; 
 +      v1: tMyVector1; 
 +   
 +  PROCEDURE (v: tVector)Log*, NEW, ABSTRACT; 
 +   
 +  PROCEDURE (v: tMyVector)Log*(), EXTENSIBLE; 
 +  BEGIN 
 +      Log.Real(v.x); Log.Real(v.y); Log.Ln 
 +  END Log; 
 +   
 +  PROCEDURE (v: tMyVector1)Log*(); 
 +  BEGIN 
 +      Log.String("Привет, мир!"); Log.Ln; 
 +      Log.Real(v.x);Log.Real(v.y); Log.Real(v.z); Log.Ln; 
 +      Log.String("-------------"); Log.Ln; 
 +  END Log; 
 +   
 +  PROCEDURE Start*; 
 +  BEGIN 
 +      v.Log; 
 +      v1.Log 
 +  END Start; 
 +   
 +  BEGIN 
 +      NEW (v); 
 +      NEW (v1); 
 +  END Test_ext_method. 
 + 
 +  (!)Test_ext_method.Start 
 +   
 +  компилируется "Test_ext_method"   248   8 
 +  старый модуль Test_ext_method выгружен 
 +   0.0 0.0 
 +  Привет, мир! 
 +   0.0 0.0 0.0 
 +  -------------
 В модуле определено три типа: tpVector, tpMyVector и tpMyVector1. Причём, все они являются друг другу базовыми. В каждом типе добавляется по одному полю, и переопределяется метод Log (кроме, разумеется самого "древнего" типа, который полностью абстрактный — tpVector). В первом типе метод Log — абстрактный, с ним вообще нельзя работать. Во втором случае — уже работает, и его можно переопределять. А в третьем случае, метод не помечен как EXTENSIBLE, а это значит, что если вдруг возникнет необходимость, например, в типе tpMyVector2 изменить этот метод — ничего не выйдет. Компилятор такое действие запретит.  [↑] В модуле определено три типа: tpVector, tpMyVector и tpMyVector1. Причём, все они являются друг другу базовыми. В каждом типе добавляется по одному полю, и переопределяется метод Log (кроме, разумеется самого "древнего" типа, который полностью абстрактный — tpVector). В первом типе метод Log — абстрактный, с ним вообще нельзя работать. Во втором случае — уже работает, и его можно переопределять. А в третьем случае, метод не помечен как EXTENSIBLE, а это значит, что если вдруг возникнет необходимость, например, в типе tpMyVector2 изменить этот метод — ничего не выйдет. Компилятор такое действие запретит.  [↑]
   
Строка 39: Строка 142:
  
 Пример использования супер-вызова приведён ниже: Пример использования супер-вызова приведён ниже:
- +  MODULE Test_super_method; 
 +   
 +  IMPORT Log; 
 +   
 +  TYPE 
 +      tVector = POINTER TO EXTENSIBLE RECORD 
 +          x*: REAL; 
 +      END; 
 +       
 +      tMyVector = POINTER TO RECORD (tVector) 
 +          y*: REAL; 
 +      END; 
 +   
 +   
 +  VAR 
 +      v: tVector; 
 +      v1: tMyVector; 
 +   
 +  PROCEDURE (v: tVector)Log*(), NEW, EXTENSIBLE; 
 +  BEGIN 
 +      Log.Real(v.x); Log.Ln 
 +  END Log; 
 +   
 +  PROCEDURE (v: tMyVector)Log*(); 
 +  BEGIN 
 +      Log.String("Привет, мир!"); Log.Ln; 
 +      Log.Real(v.y);v.Log^; 
 +      Log.String("-------------"); Log.Ln; 
 +  END Log; 
 +   
 +  PROCEDURE Start*; 
 +  BEGIN 
 +      v.Log; 
 +      v1.Log 
 +  END Start; 
 +   
 +  BEGIN 
 +      NEW (v); 
 +      NEW (v1); 
 +  END Test_super_method. 
 + 
 +  (!)Test_super_method.Start 
 +   
 +  компилируется "Test_super_method"   200   8 
 +  старый модуль Test_super_method выгружен 
 +   0.0 
 +  Привет, мир! 
 +   0.0 0.0 
 +  -------------
 В примере хорошо видно, что супер-вызов оформлен в виде инструкции v.Log^. Вместо того, чтобы заново переписывать всю логику в методе, было дописано лишь часть кода до и после супер-вызова. Кроме того, часто бывает так, что у программиста нет возможности внести изменения в базовый класс (например, модуль получен в виде уже готового исполняемого машинного кода). [↑] В примере хорошо видно, что супер-вызов оформлен в виде инструкции v.Log^. Вместо того, чтобы заново переписывать всю логику в методе, было дописано лишь часть кода до и после супер-вызова. Кроме того, часто бывает так, что у программиста нет возможности внести изменения в базовый класс (например, модуль получен в виде уже готового исполняемого машинного кода). [↑]
   
bb/redbook/211.1459848275.txt.gz · Последнее изменение: 2020/10/29 07:08 (внешнее изменение)