Здесь показаны различия между двумя версиями данной страницы.
Предыдущая версия справа и слева Предыдущая версия | |||
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 | ||
В приведённом коде всё ещё сохраняется ошибка со списанием денег. Решить эту проблему предлагается самостоятельно в качестве задания. | В приведённом коде всё ещё сохраняется ошибка со списанием денег. Решить эту проблему предлагается самостоятельно в качестве задания. | ||
[↑] | [↑] |