pascalabcnet/PABCNetHelp/LangGuide/Classes/indexedproperties.html

113 lines
7.7 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<html>
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="Индексные свойства">
<param name="Keyword" value="Расширенные индексные свойства">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<H1>Индексные свойства</H1>
<p>Индексные свойства ведут себя аналогично полям-массивам и
используются, как правило, для доступа к элементам контейнеров.
Как и при использовании обычных свойств, при использовании индексных свойств
могут попутно выполняться некоторые действия.
</p>
<p>Индексное свойство описывается в классе следующим
образом:</p>
<blockquote>
<p><code><b>property</b> Prop[<code class="codeit">описание индексов</code>]: <code class="codeit">тип</code> <b>read</b>
<code class="codeit">IndexedPropertyReader</code> <b>
write</b>
<code class="codeit">IndexedPropertyWriter</code>;</code></p>
</blockquote>
<p>В качестве <code><code class="codeit">IndexedPropertyReader</code></code> может
выступать: </p>
<ul>
<li><em>имя функции чтения индексного свойства</em>;</li>
<li><em>выражение</em> соответствующего типа (в этом случае индексное свойство
называется <em>расширенным</em>). </li>
</ul>
<p>В качестве <code><code class="codeit">IndexedPropertyWriter</code></code> может
выступать: </p>
<ul>
<li><em>имя процедуры записи индексного свойства</em>;</li>
<li><em>оператор</em> (в этом случае индексное свойство называется <em>расширенным</em>).
В операторе доступна предопределённая переменная value, в которую помещается
значение для изменения свойства.</li>
</ul>
<p>Функция чтения и процедура записи должны быть методами этого класса и иметь
следующий вид:</p>
<blockquote>
<p><code><b>function</b> GetProp(<code class="codeit">описание индексов</code>): <code class="codeit">
тип</code>;<b><br>
procedure</b> SetProp(<code class="codeit">описание индексов</code>; value: <code class="codeit">тип</code>);</code></p>
</blockquote>
<p>В простейшем случае одного индекса описание индексного свойства выглядит так:</p>
<blockquote>
<p><code><b>property</b> Prop[ind: <code class="codeit">
тип индекса</code>]: <code class="codeit">тип</code> <b>read</b>
GetProp <b>
write</b> SetProp;</code></p>
</blockquote>
<p>Всякий раз, когда мы для объекта <code>a</code>, содержащего свойство <code>
Prop</code>, выполняем присваивание <code>a.Prop[ind] := value</code>,
вызывается процедура <code>a.SetProp(ind,value)</code>, а
когда считываем значение
<code>a.Prop[ind]</code>, вызывается функция
<code>a.GetProp(ind)</code>.</p>
<p>Индексное свойство, после которого добавлено ключевое слово <b><code>default</code></b> с последующей <code>;</code>, называется <i><b><font color="#FF0000">ин</font></b><font color="#FF0000"><b>дексным
свойством по умолчанию</b></font></i> и позволяет пользоваться объектами класса как массивами, т.е.
использовать запись <code>a[ind]</code> <i>вместо </i> <code>a.Prop[ind]</code>. </p>
<p>Принципиальное отличие индексных свойств от полей-массивов
состоит в том, что тип индекса может быть произвольным (в частности, строковым).&nbsp;Это
позволяет легко реализовать так называемые ассоциативные массивы, элементы
которых индексируются строками. </p>
<p>В следующем примере индексное свойство используется для закрашивания клеток шахматной доски
белым или в графическом режиме.</p>
<blockquote>
<p><code><strong>uses</strong> GraphWPF;<br><strong>const</strong> <br>&nbsp;
n = 8;<br>&nbsp; sz = 50;<br><strong>type</strong> <br>&nbsp; ChessBoard =
class<br>&nbsp; <strong>private</strong><br>&nbsp;&nbsp;&nbsp; a: <strong>
array</strong> [,] <strong>of</strong> boolean := new boolean[n,n];<br>&nbsp;&nbsp;&nbsp;
<strong>procedure</strong> setCell(x,y: integer; value: boolean);<br>&nbsp;&nbsp;&nbsp;
<strong>begin</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>if</strong>
value <strong>then</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Brush.Color := Colors.White<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>else</strong>
Brush.Color := Colors.Gray;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
FillRectangle((x-1)*sz+1,(y-1)*sz+1,sz,sz);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
a[x-1,y-1] := value;<br>&nbsp;&nbsp;&nbsp; <strong>end</strong>;<br>&nbsp;&nbsp;&nbsp;
<strong>function</strong> getCell(x,y: integer) := a[x-1,y-1];<br>&nbsp;
<strong>public</strong><br>&nbsp;&nbsp;&nbsp; <strong>property</strong>
Cells[x,y: integer]: boolean <strong>read</strong> getCell <strong>write</strong>
setCell; <strong>default</strong>;<br><strong>end</strong>;<br><br><strong>
var</strong> c: ChessBoard := new ChessBoard;<br><br><strong>begin</strong><br>&nbsp;
<strong>for</strong> <strong>var</strong> x:=1 <strong>to</strong> n <strong>
do</strong><br>&nbsp; <strong>for</strong> <strong>var</strong> y:=1 <strong>
to</strong> n <strong>do</strong><br>&nbsp;&nbsp;&nbsp; c[x,y] := Odd(x+y);
<br><strong>end</strong>.</code></p>
</blockquote>
<p>Можно не писать отдельные методы <code>getCell</code> и <code>setCell</code>
для доступа к свойству на чтение и запись, а воспользоваться <em>расширенными
индексными свойствами</em>:</p>
<blockquote>
<p><code><strong>type</strong> <br>&nbsp; ChessBoard = class<br>&nbsp;
<strong>private</strong><br>&nbsp;&nbsp;&nbsp; a: <strong>array</strong> [,]
<strong>of</strong> boolean := new boolean[n,n];<br>&nbsp; <strong>public</strong><br>&nbsp;&nbsp;&nbsp;
<strong>property</strong> Cells[x,y: integer]: boolean <strong><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
read</strong> a[x-1,y-1] <strong><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; write</strong>
<strong>begin</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>
if</strong> value <strong>then</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Brush.Color := Colors.White<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<strong>else</strong> Brush.Color := Colors.Gray;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
FillRectangle((x-1)*sz+1,(y-1)*sz+1,sz,sz);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
a[x-1,y-1] := value;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>end</strong>;
<strong>default</strong>;<br><strong>end</strong>;</code></p>
</blockquote>
</body>
</html>