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

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


bb:redbook:208

Различия

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

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

Предыдущая версия справа и слева Предыдущая версия
bb:redbook:208 [2019/07/23 11:35]
caufman [2. Свойства объекта]
bb:redbook:208 [2019/07/23 13:11] (текущий)
caufman [3. Методы объекта]
Строка 49: Строка 49:
 ==== 3. Методы объекта ==== ==== 3. Методы объекта ====
 Как уже было упомянуто,​ метод — это процедуры привязанная к данным. Т. е. процедура требует данные определённого типа. И при этом, поскольку такая процедура привязана,​ она может быть вызвана с нотацией через точку ("​."​),​ что частично облегчает понимание текста программы. Давайте положим что-нибудь на счёт: Как уже было упомянуто,​ метод — это процедуры привязанная к данным. Т. е. процедура требует данные определённого типа. И при этом, поскольку такая процедура привязана,​ она может быть вызвана с нотацией через точку ("​."​),​ что частично облегчает понимание текста программы. Давайте положим что-нибудь на счёт:
-  +  PROCEDURE (VAR p: tPerson) Accum* (m: REAL), NEW; 
- +  ​BEGIN 
 +      p.count := p.count + m; 
 +      Log.Real(p.count);​ Log.Ln 
 +  END Accum;
 Этот метод (процедура специального вида) принимает параметр (VAR self: tPerson) в качестве скрытой ссылки. В последствие,​ вызов person.Accum(n) будет выглядеть именно так, где person — есть объект типа tPerson. После имени метода Accum* (который между прочим экспортирован) имеет в качестве аргумента некоторое число денег m. Эта сумма прибавляется к тому, что уже хранится на счёте, после чего новая сумма выводится на экран. Если эта операция выполняется вручную,​ убедиться,​ что зачисление прошло — лишним не будет. Ключевое слово VAR имеет в объявлении функции специальный смысл, пока не рассматриваем (существует и другой способ привязки процедуры к типу). Ключевое слово NEW в данном случае,​ говорит о том, что у объекта tPerson появился новый метод, который ранее не существовал. Этот метод (процедура специального вида) принимает параметр (VAR self: tPerson) в качестве скрытой ссылки. В последствие,​ вызов person.Accum(n) будет выглядеть именно так, где person — есть объект типа tPerson. После имени метода Accum* (который между прочим экспортирован) имеет в качестве аргумента некоторое число денег m. Эта сумма прибавляется к тому, что уже хранится на счёте, после чего новая сумма выводится на экран. Если эта операция выполняется вручную,​ убедиться,​ что зачисление прошло — лишним не будет. Ключевое слово VAR имеет в объявлении функции специальный смысл, пока не рассматриваем (существует и другой способ привязки процедуры к типу). Ключевое слово NEW в данном случае,​ говорит о том, что у объекта tPerson появился новый метод, который ранее не существовал.
  
 C начислением всё в порядке. Давайте теперь немного денег потратим:​ C начислением всё в порядке. Давайте теперь немного денег потратим:​
-  +  PROCEDURE (VAR p: tPerson) Debet* (m: REAL), NEW; 
- +  ​BEGIN 
 +      p.count := p.count - m; 
 +      Log.Real(p.count);​ Log.Ln 
 +  END Debet;
 По аналогии с предыдущим методом здесь происходит получение скрытой ссылки на объект типа tPerson и вычитание указанной суммы со счёта. В обоих методах скрывается существенная ошибка,​ которая демонстрируется выполнением следующего кода: По аналогии с предыдущим методом здесь происходит получение скрытой ссылки на объект типа tPerson и вычитание указанной суммы со счёта. В обоих методах скрывается существенная ошибка,​ которая демонстрируется выполнением следующего кода:
-  +  PROCEDURE Start*; 
-  +  BEGIN 
- +      ​anonim.Accum(50);​ 
 +      anonim.Debet(60) 
 +  END Start; 
 + 
 +  компилируется "​TestPerson"​ 
 +  Start  теперь в символьном файле ​  ​208 ​  532 
 +  старый модуль TestPerson выгружен 
 +  50.0 
 +  -10.0
 Списано денег больше,​ чем есть на счёте. Пополнение счёта также может привести к ошибке (если объект anonim является невероятно богатым человеком;​ это всё из-за типа REAL). В тоже время, можно зачислить отрицательную сумму. Что в обычной практике — не допускается. Списано денег больше,​ чем есть на счёте. Пополнение счёта также может привести к ошибке (если объект anonim является невероятно богатым человеком;​ это всё из-за типа REAL). В тоже время, можно зачислить отрицательную сумму. Что в обычной практике — не допускается.
  
 Полный текст программы представлен ниже: Полный текст программы представлен ниже:
-  +  MODULE TestPerson;​ 
 +  (* модуль описывает объект банковского учёта *) 
 +   
 +  IMPORT Log; 
 +   
 +  TYPE 
 +      tPerson = RECORD (* объект человек *) 
 +          name-: ARRAY 128 OF CHAR; (* имя *) 
 +          family-: ARRAY 128 OF CHAR; (* фамилия *) 
 +          age: SHORTINT; (* возраст *) 
 +          id-: INTEGER; (* уникальный идентификатор *) 
 +          subset-: INTEGER; (* счёт в банке *) 
 +          count: REAL (* сколько денег на счёте *) 
 +      END; 
 +   
 +  VAR 
 +      anonim*: tPerson; 
 +   
 +  PROCEDURE (VAR p: tPerson) Accum* (m: REAL), NEW; 
 +  BEGIN 
 +      p.count := p.count + m; 
 +      Log.Real(p.count);​ Log.Ln 
 +  END Accum; 
 +   
 +  PROCEDURE (VAR p: tPerson) Debet* (m: REAL), NEW; 
 +  BEGIN 
 +      p.count := p.count - m; 
 +      Log.Real(p.count);​ Log.Ln 
 +  END Debet; 
 +   
 +  PROCEDURE Start*; 
 +  BEGIN 
 +      anonim.Accum(50);​ 
 +      anonim.Debet(60) 
 +  END Start; 
 +   
 +  BEGIN 
 +  END TestPerson. 
 +   
 +  (!)TestPerson.Start
 В приведённом коде всё ещё сохраняется ошибка со списанием денег. Решить эту проблему предлагается самостоятельно в качестве задания. В приведённом коде всё ещё сохраняется ошибка со списанием денег. Решить эту проблему предлагается самостоятельно в качестве задания.
 [↑] [↑]
bb/redbook/208.txt · Последние изменения: 2019/07/23 13:11 — caufman