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">
|
|||
|
|
</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>
|
|||
|
|
<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>
|
|||
|
|
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>
|
|||
|
|
Person = <b>class<br>
|
|||
|
|
|
|||
|
|
...<br>
|
|||
|
|
function</b> ToString:
|
|||
|
|
string; <b>override</b>;<br>
|
|||
|
|
<b> begin</b><br> Result :=
|
|||
|
|
|
|||
|
|
string.Format('Имя: {0} Возраст: {1}',
|
|||
|
|
Name, Age); <br>
|
|||
|
|
<b> end</b>;<br>
|
|||
|
|
<b> end</b>;<br>
|
|||
|
|
...<br>
|
|||
|
|
<b>var</b> p: Person := new Person('Иванов',20);<br>
|
|||
|
|
writeln(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>writeln(p1=p2); // False<br>
|
|||
|
|
p2 := p1; <br>
|
|||
|
|
writeln(p1=p2); // True</code></p>
|
|||
|
|
</blockquote>
|
|||
|
|
<p>Это поведение можно изменить, <A href="operoverloading.html">перегрузив</A>
|
|||
|
|
операцию = для класса.</p>
|
|||
|
|
</body>
|
|||
|
|
|