155 lines
8.6 KiB
HTML
155 lines
8.6 KiB
HTML
<html>
|
||
|
||
<head>
|
||
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
|
||
<param name="Keyword" value="class">
|
||
<param name="Keyword" value="sealed">
|
||
</object>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
|
||
<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>
|
||
<code class="codeit">имя класса</code><b> </b>=<b> class</b><br>
|
||
<code class="codeit"> секция1</code> <br>
|
||
<code class="codeit"> секция2</code> <br><code class="codeit">
|
||
...</code><br>
|
||
<b>end</b>;</code></p>
|
||
</blockquote>
|
||
<p>Каждая секция имеет вид:</p>
|
||
<blockquote>
|
||
<p><code><code class="codeit"><A href="visibility.html">модификатор доступа</A></code>
|
||
<br><code class="codeit"> описания полей</code><br>
|
||
<code class="codeit">
|
||
объявления или описания методов и описания свойств</code></code></p>
|
||
</blockquote>
|
||
<p>Модификатор доступа в первой секции может отсутствовать, при этом
|
||
подразумевается модификатор <strong><span class="auto-style1">internal</span></strong>
|
||
(видимость всюду внутри сборки).</p>
|
||
<p>Методы могут описываться как внутри, так и вне класса. При описании метода
|
||
внутри класса его имя предваряется именем класса с последующей точкой. Например:</p>
|
||
<blockquote>
|
||
<p><code><b>type</b><br>
|
||
Person = <strong>class</strong><b><br>
|
||
private</b><br>
|
||
fName: string;<br>
|
||
fAge: integer;<br>
|
||
<b> public</b><br>
|
||
<b>constructor</b> Create(Name: string; Age: integer);<br>
|
||
<b>begin</b><br>
|
||
fName := Name;<br>
|
||
fAge := Age;<br>
|
||
<b>end</b>;<br><strong> procedure</strong>
|
||
Print;<br><b> property</b> Name: string read fName;<br><b>
|
||
property</b> Age: integer read fAge;<b><br> end</b>;<br><strong><br>
|
||
procedure</strong> Person.Print;<br><strong>begin</strong><br>
|
||
Println($'Имя: {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>
|
||
Person = <b>class<br>
|
||
|
||
...<br>
|
||
function</b> ToString:
|
||
string; <b>override</b>;<br>
|
||
<b> begin</b><br> Result :=
|
||
|
||
$'Имя: {Name} Возраст: {Age}'; <br>
|
||
<b> end</b>;<br>
|
||
<b> end</b>;<br>
|
||
...<br>
|
||
<b>var</b> p: Person := new Person('Иванов',20);<br>
|
||
Println(p); // Имя: Иванов Возраст: 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; // Имя: Петров
|
||
Возраст: 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>Println(p1 = p2); // False<br>
|
||
p2 := p1; <br>
|
||
Println(p1 = p2); // True</code></p>
|
||
</blockquote>
|
||
<p>Это поведение можно изменить, <A href="operoverloading.html">перегрузив</A>
|
||
операцию = для класса.</p>
|
||
</body>
|
||
|