Шрифт:
Интервал:
Закладка:
Каждое поле, метод или свойство класса имеет модификатор (атрибут) доступа, задающий правила его видимости. В PascalABC.NET существуют четыре вида модификаторов доступа: public (открытый), private (закрытый), protected (защищенный) и internal (внутренний). К члену класса, имеющему атрибут public, можно обратиться из любого места программы, члены класса с атрибутом private доступны только внутри методов этого класса, члены класса с атрибутом protected доступны внутри методов этого класса и всех его подклассов, члены класса с атрибутом internal доступны внутри сборки (термин .NET, сборка в нашем понимании - это множество файлов, необходимых для генерации .exe или .dll-файла). Кроме того, private и protected члены видны отовсюду в пределах модуля, в котором определен класс.
Тело класса делится на секции. В начале каждой секции располагается модификатор доступа, после которого идут поля, а затем методы и свойства с доступом, определяемым этим модификатором. В первой секции модификатор доступа может отсутствовать, в этом случае подразумевается модификатор internal. В классе может быть произвольное количество секций, располагающихся в произвольном порядке.
Например, пусть данный код располагается в одном модуле:
type
A = class
private
x: integer;
protected
a: integer;
public
constructor Create(xx: integer)
begin
x := xx; // верно, т.к. внутри метода класса можно обращаться к его закрытому полю x
a := 0; // верно
end;
;
Следующий же код пусть располагается в другом модуле: type
B = class(A)
public
procedure print;
begin
writeln(a); // верно, т.к. a - защищенное поле
writeln(x); // неверно, т.к. х - закрытое поле
end;
end;
...
var b1: B := new B(5);
...
writeln(b1.x); // неверно, т.к. х - закрытое поле
writeln(b1.a); // неверно, т.к. a - защищенное поле
b1.print; // верно, т.к. print - открытый метод
Комментарии по тексту программы описывают верное и неверное в смысле доступа обращение к полям и методам.
Методы
Методы представляют собой процедуры и функции, объявленные внутри класса или записи. Особыми разновидностями методов являются конструкторы, деструкторы и перегруженные операции.
Определение методов можно давать как внутри класса (стиль Java, C#, C++), так и вне класса (стиль Delphi, C++). При определении метода вне интерфейса класса его имя предваряется именем класса с последующей точкой. Например:
type
Rectangle = class
x1,y1,x2,y2: integer;
constructor Create(xx1,yy1,xx2,yy2: integer);
begin
x1 := xx1; x2 := xx2;
y1 := yy1; y2 := yy2;
end;
function Square: integer;
end;
function Rectangle.Square: integer;
begin
Result := abs(x2-x1) * abs(y2-y1);
end;
Обычно когда класс определяется в интерфейсной части модуля, то в интерфейсе класса производят лишь объявление методов, реализацию же методов класса дают в секции реализации модуля.
Методы делятся на классовые и экземплярные. Классовые методы в .NET называются статическими. Объявление классового метода начинается с ключевого слова class. Экземплярные методы можно вызывать только через переменную-объект класса. Классовые же методы не связаны с конкретным экземпляром класса; их следует вызывать в виде:
имя класса.имя метода(параметры)
Внутри классового метода не может быть обращения к полям класса, а может быть только обращение к другим классовым методам. Напротив, экземплярный метод может вызывать классовый.
Например:
type
Rectangle = class
...
class procedure Move(var r: Rectangle; dx,dy: integer);
begin
r.x1 += dx; r.x2 += dx;
r.y1 += dy; r.y2 += dy;
end;
end;
...
var r := new Rectangle(10,10,100,100);
Rectangle.Move(r,5,5);
По существу, классовые методы являются разновидностью глобальных подпрограмм, но находятся внутри класса, что подчеркивает, что они осуществляют действия, связанные именно с этим классом. Класс в этом случае выступает только в роли пространства имен.
Нередко создаются классы, целиком состоящие из классовых методов. Таков, например, класс System.Math, содержащий определения математических подпрограмм.
Инициализаторы полей
При создании объекта его поля инициализируются автоматически нулевыми значениями если они не инициализированы явно. Их инициализация может проводиться как в конструкторе, так и непосредственно при описании. Инициализация поля при описании приводит к тому, что код инициализации вставляется в начало ВСЕХ конструкторов.
Например:
type
A = class
private
x: integer := 1;
y: integer;
l := new List<integer>;
public
constructor Create(xx,yy: integer);
begin
x := xx;
y := yy;
end;
constructor Create;
begin
end;
end;
В данном примере код x:=1; l := new List<integer> вставляется в начало каждого конструктора.
Конструкторы
Объекты создаются с помощью специальных методов, называемых конструкторами.
Конструктор представляет собой функцию, создающую объект в динамической памяти, инициализирующую его поля и возвращающую указатель на созданный объект. Этот указатель обычно сразу присваивается переменной типа класс. При описании конструктора вместо служебного слова function используется служебное слово constructor. Кроме того, для конструктора не указывается тип возвращаемого значения.
Например:
type
Person = class
private
nm: string;
ag: integer;
public
constructor Create(name: string; age: integer);
end;
...
constructor Person.Create(name: string; age: integer);
begin
nm := name;
ag := age;
end;
В PascalABC.NET конструктор всегда должен иметь имя Create. При описании конструктора внутри класса можно опускать его имя:
type
Person = class
constructor (name: string; age: integer);
begin
nm := name;
ag := age;
end;
end;
В силу особенностей реализации вызовов конструкторов в .NET в PascalABC.NET всегда создается конструктор без параметров (независимо от того, определен ли другой конструктор). Этот конструктор инициализирует все поля нулевыми значениями (строковые поля - пустыми строками, логические - значением False).
Для вызова конструктора можно использовать два способа.
1 способ. В стиле Object Pascal.
Для вызова конструктора следует указать имя класса, за которым следует точка-разделитель, имя конструктора и список параметров. Например:
var p: Person;
p := Person.Create('Иванов',20);
2 способ. С помощью операции new - в стиле C# (предпочтительный).
var p: Person;
p := new Person('Иванов',20);
Деструктор в Object Pascal - специальная процедура, уничтожающая объект и освобождающая динамическую память, которую этот объект занимал. При описании деструктора вместо служебного слова procedure используется служебное слово destructor.
Например:
destructor Destroy;
begin
...
end;
Поскольку в PascalABC.NET память управляется сборщиком мусора, деструктор в PascalABC.NET не играет никакой роли и представляет собой обычную процедуру-метод.
Предварительное объявление классов
Два или более класса могут содержать в качестве полей объекты других классов, циклически ссылающиеся друг на друга.
Например:
type
AAA = class
b: BBB;
end;
BBB = class
a: AAA;
end;
Данный код вызовет ошибку компиляции, поскольку тип BBB в момент описания поля b еще не определен. В такой ситуации следует воспользоваться предварительным описанием класса в виде
ИмяКласса = class;
Предварительно описанный класс должен быть полностью описан в той же секции type:
type
BBB = class;
AAA = class
b: BBB;
end;
BBB = class
a: AAA;
end;
Переменная Self
Внутри каждого нестатического метода неявно определяется переменная Self, ссылающаяся на объект, вызвавший этот метод.
Например:
type
A = class
i: integer;
constructor Create(i: integer);
begin
- Математические диктанты. Числовые примеры. Все типы задач. Устный счет. 1-2 классы - Елена Нефедова - Детская образовательная литература
- ФСБ. Машина смерти. Чекист остается чекистом. (СИ) - Сокольников Борис - Детская образовательная литература
- Новейшие сочинения. Все темы 2011: 5-9 классы - Людмила Бойко - Детская образовательная литература