pascalabcnet/PABCNetHelp/LangGuide/_ProgrStruct_Defs/scope.html

126 lines
7.7 KiB
HTML
Raw Permalink Normal View History

<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>
Основная программа, подпрограмма, <a href="../Operators/beginend.html">блок</a>,
<a href="../Modules/indexmodule.html">модуль</a>, <a href="../Classes/index_classes.html">
класс</a> образуют так называемое <i>
<b><font color="#FF0000">пространство имен</font></b></i> - область в программе,
в которой имя должно иметь единственное описание. Таким образом, в одном
пространстве имен не может быть описано двух одинаковых имен (исключение
составляют <a href="../ProcFunc/overloading.html">перегруженные имена подпрограмм</a>).
Кроме того, в сборках .NET имеются явные
определения пространств имен.</p>
<p>
<i>Область
действия идентификатора</i> (т.е. место, где он может быть использован) простирается
от момента описания до конца блока, в котором он описан. Область действия глобального идентификатора, описанного в модуле, простирается на весь модуль,
а также на основную программу, к которой данный модуль подключен в разделе
<b><code>uses</code></b>.</p>
<p>
Кроме этого, имеются переменные, определенные в блоке и связанные с некоторыми
конструкциями (<b><code>for</code></b>, <b><code>foreach</code></b>). В этом
случае действие переменной <code>i</code> простирается до конца соответствующей
конструкции. Так, следующий код корректен: </p>
<blockquote>
<p><code><b>var </b>a: <b>array of</b> integer := (3,5,7);<b><br>
for</b> <strong>var </strong>i := 1 <b>to</b> 9 <b>do</b> <br>
&nbsp; Print(a[i]); <br>
<b>foreach</b> <strong>var </strong>i <b>in</b> a <b>do</b> <br>
&nbsp; Print(i);</code></p>
</blockquote>
<p>
Идентификатор с тем же именем, определенный во вложенном пространстве имен, <i>скрывает</i>
идентификатор, определенный во внешнем пространстве имен. Например, в коде</p>
<blockquote>
<p><code><b>var </b>i: integer;</code></p>
<p><code><b>procedure</b> p;<br>
<b>var</b> i: integer;<br>
<b>begin</b><br>
&nbsp; i := 5;<br>
<b>end</b>;</code></p>
</blockquote>
<p>значение 5 будет присвоено переменной <code>i</code>, описанной в процедуре
<code>p</code>; внутри же процедуры <code>p</code>
сослаться на глобальную переменную <code>i</code>
невозможно.</p>
<p>Переменные, описанные внутри блока, не могут иметь те же имена, что и
переменные из раздела описаний этого блока. Например, следующая программа
ошибочна:</p>
<blockquote>
<p><code><b>var</b> i: integer;<br>
<b>begin</b><br>
<b>&nbsp; var</b> i: integer; // ошибка<br>
<b>end</b>.</code></p>
</blockquote>
<p>В производных классах, напротив, можно определять члены с теми же именами, что и в базовых классах, при
этом их имена скрывают соответствующие имена в базовых классах.
Для обращения к одноименному члену базового класса из метода производного класса используется
ключевое слово <b><code>
<a href="../Classes/inherited.html">inherited</a></code></b>:</p>
<blockquote>
<p><code><b>type</b><br>
&nbsp; A =<b> class</b><br>
&nbsp;&nbsp;&nbsp; i: integer;<br>
&nbsp;&nbsp;&nbsp; <b>procedure</b> p;<br>
&nbsp;&nbsp;&nbsp; <b>begin</b><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i := 5;<br>
&nbsp;&nbsp;&nbsp; <b>end</b>;<br>
&nbsp; <b>end</b>;<br>
&nbsp; B =<b> class</b>(A)<br>
&nbsp;&nbsp;&nbsp; i: integer;<br>
&nbsp;&nbsp;&nbsp; <b>procedure</b> p;<br>
&nbsp;&nbsp;&nbsp; <b>begin</b><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i := 5;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>inherited</b> p;<br>
&nbsp;&nbsp;&nbsp; <b>end</b>;<br>
&nbsp; <b>end</b><b>;</b></code></p>
</blockquote>
<p><font color="#FF0000"><i><b>Алгоритм поиска имени в классе </b></i></font>
следующий: вначале имя ищется в текущем классе, затем в его базовых классах, а
если не найдено, то в глобальной области видимости.</p>
<p><font color="#FF0000"><i><b>Алгоритм поиска имени в глобальной области
видимости при наличии нескольких подключенных модулей</b></i></font> следующий:
вначале имя ищется в текущем модуле, затем, если не найдено, по цепочке
подключенных модулей в порядке справа налево. Например, в программе</p>
<blockquote>
<p><code><b>uses</b> unit1,unit2;<br>
<b>begin</b><br>
&nbsp; id := 2;<br>
<b>end</b>.</code></p>
</blockquote>
<p>описание переменной <code>id</code> будет искаться вначале в основной
программе, затем в модуле <code>unit2</code>, затем в модуле <code>unit1</code>.
При этом в разных модулях могут быть описаны разные переменные <code>id</code>.
Данная ситуация означает, что <code>unit1</code> образует внешнее пространство
имен, пространство имен <code>unit2</code> в него непосредственно вложено, а
пространство имен основной программы вложено в <code>unit2</code>.</p>
<p>Если в последнем примере оба модуля - <code>unit1</code> и <code>unit2</code>
- определяют переменные <code>id</code>, то рекомендуется уточнять имя
переменной именем модуля, используя конструкцию <i>
ИмяМодуля</i><code>.</code><i>Имя</i>:</p>
<blockquote>
<p><code><b>uses</b> unit1,unit2;<br>
<b>begin</b><br>
&nbsp; unit1.id := 2;<br>
<b>end</b>.</code></p>
</blockquote>
<p>&nbsp;</p>
</body>
</html>