pascalabcnet/PABCNetHelp/LangGuide/Classes/index_classes.html

155 lines
8.6 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="class">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Классы и объекты: обзор</title>
<link rel="StyleSheet" href="../../default.css">
<style type="text/css">
.auto-style1 {
font-family: monospace;
font-size: 10pt;
color: #000080;
}
</style>
</head>
<body>
<H1>Обзор классов и объектов</H1>
<h2>Описание классов</h2>
<p>Класс представляет собой составной тип, состоящий из полей
(переменных), <A href="methods.html">методов</A> (процедур и функций)
и <A href="properties.html">свойств</A>. Описание класса имеет вид:</p>
<blockquote>
<p><code><b>type</b> <br>
&nbsp; <code class="codeit">имя класса</code><b> </b>=<b> class</b><br>
&nbsp; <code class="codeit">&nbsp; секция1</code>&nbsp; <br>&nbsp;
<code class="codeit">&nbsp; секция2</code>&nbsp; <br><code class="codeit">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
...</code><br>
&nbsp; <b>end</b>;</code></p>
</blockquote>
<p>Каждая секция имеет вид:</p>
<blockquote>
<p><code><code class="codeit"><A href="visibility.html">модификатор доступа</A></code>&nbsp;
<br><code class="codeit">&nbsp;&nbsp; описания полей</code><br>
<code class="codeit">&nbsp;&nbsp;
объявления или описания методов и описания свойств</code></code></p>
</blockquote>
<p>Модификатор доступа в первой секции может отсутствовать, при этом
подразумевается модификатор <strong><span class="auto-style1">internal</span></strong>
(видимость всюду внутри сборки).</p>
<p>Методы могут описываться как внутри, так и вне класса. При описании метода
внутри класса его имя предваряется именем класса с последующей точкой. Например:</p>
<blockquote>
<p><code><b>type</b><br>
&nbsp; Person = <strong>class</strong><b><br>
&nbsp; private</b><br>
&nbsp;&nbsp;&nbsp; fName: string;<br>
&nbsp;&nbsp;&nbsp; fAge: integer;<br>
<b>&nbsp; public</b><br>
&nbsp;&nbsp;&nbsp; <b>constructor</b> Create(Name: string; Age: integer);<br>
&nbsp;&nbsp;&nbsp; <b>begin</b><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fName := Name;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fAge := Age;<br>
&nbsp;&nbsp;&nbsp; <b>end</b>;<br><strong>&nbsp;&nbsp;&nbsp; procedure</strong>
Print;<br><b>&nbsp;&nbsp;&nbsp; property</b> Name: string read fName;<br><b>&nbsp;&nbsp;&nbsp;
property</b> Age: integer read fAge;<b><br>&nbsp; end</b>;<br><strong><br>
procedure</strong> Person.Print;<br><strong>begin</strong><br>&nbsp;
writelnFormat('Имя: {0} Возраст: {1}', Name, Age);<br><strong>end</strong>;</code></p>
</blockquote>
<p>После слова <code><b>class</b></code>
в скобках может быть указано имя класса-предка (см. <A href="inheritance.html">
Наследование</A>), а также через запятую список поддерживаемых
<A href="../Interfaces/indexinterf.html">интерфейсов</A>. </p>
<p>Перед словом <code><b>class</b></code>
может быть указано ключевое слово <code><b>sealed</b></code> в
этом случае от класса запрещено <A href="inheritance.html">наследовать</A>.</p>
<p>Все описания и объявления внутри класса образуют <b>
<font color="#ff0000"><i>тело класса</i></font></b>. Поля и
методы образуют <b><font color="#ff0000"> <i>интерфейс</i></font></b> класса. Инициализаторы полей описаны <A href="initfields.html">здесь</A>. </p>
<p>Классы могут описываться только на глобальном уровне. Локальные определения классов (т.е. определения в
разделе описания подпрограмм) запрещены.</p>
<h2>Переменные типа класс</h2>
<p>В языке <strong>PascalABC.NET</strong> классы являются
<A href="../Types/value_ref_types.html">ссылочными типами</A>.
Это значит, что переменная типа класс хранит в действительности ссылку на
объект. </p>
<p>Переменные типа класс называются <b><font color="#ff0000"><i>объектами</i></font></b>
или <b><font color="#ff0000"><i>экземплярами класса</i></font></b>. Они
инициализируются вызовом <A href="constrdestr.html">конструктора</A> класса -
специального метода, выделяющего память под объект класса и инициализирующего
его поля:</p>
<blockquote>
<p><code><strong>var</strong> p: Person := new Person('Иванов',20);</code></p>
</blockquote>
<p>После инициализации через переменную типа класс можно обращаться к публичным
членам класса (полям, методам, свойствам), используя точечную нотацию:</p>
<blockquote>
<p><code>Print(p.Name,p.Age);<br>p.Print;</code></p>
</blockquote>
<h2>Вывод переменной типа класс</h2>
<p>По умолчанию процедура <code>write</code> для переменной типа класс выводит
содержимое её публичных полей и свойств в круглых скобках через запятую:</p>
<blockquote>
<p><code>write(p); // Иванов 20</code></p>
</blockquote>
<p>Чтобы изменить это поведение, в классе следует
<A href="../Classes/virtual.html">переопределить</A> виртуальный метод
<code>ToString</code> класса <code>Object</code> - в этом случае именно он будет
вызываться при выводе объекта. </p>
<p>Например:</p>
<blockquote>
<p><code><b>type</b><br>
&nbsp; Person = <b>class<br>
&nbsp;
&nbsp; ...<br>
&nbsp; &nbsp; function</b> ToString:
string; <b>override</b>;<br>
<b>&nbsp;&nbsp;&nbsp; begin</b><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Result :=
string.Format('Имя: {0}&nbsp; Возраст: {1}',
Name, Age); <br>
<b>&nbsp;&nbsp;&nbsp; end</b>;<br>
<b>&nbsp; end</b>;<br>
&nbsp; ...<br>
<b>var</b> p: Person := new Person('Иванов',20);<br>
writeln(p); // Имя: Иванов&nbsp; Возраст: 20</code></p>
</blockquote>
<h2>Присваивание и передача в качестве параметров подпрограмм</h2>
<p>Переменная типа класс является ссылкой и хранит ссылку на объект, создаваемый
вызовом конструктора.</p>
<p>Как ссылка переменная типа класс может хранить значение <code>
<b>nil</b></code>:</p>
<blockquote>
<p><code>p :=<b> nil</b>;<br>
...<br>
if p =<b> nil</b> then ...</code></p>
</blockquote>
<p>При присваивании переменных типа класс копируется только ссылка. После
присваивания обе переменные типа класс будут ссылаться на один объект
и совместно модифицировать его:</p>
<blockquote>
<p><code><b>var</b> p1,p2: Person;<br>
...<br>
p1 := new Person('Петров',20);<br>
p2 := p1;<br>
p1.IncAge;<br>
p2.Print; // Имя: Петров&nbsp;
Возраст: 21</code></p>
</blockquote>
<h2>Сравнение на равенство</h2>
<p>При сравнении переменных типа класс на равенство сравниваются ссылки, а не
значения. </p>
<blockquote>
<p><code><b>var</b> p1 := new Person('Петров',20);<br><b>var</b> p2 := new
Person('Петров',20);<br>writeln(p1=p2); // False<br>
p2 := p1; <br>
writeln(p1=p2); // True</code></p>
</blockquote>
<p>Это поведение можно изменить, <A href="operoverloading.html">перегрузив</A>
операцию = для класса.</p>
</body>