Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Предварительное описание классов

Поиск

Обзор классов и объектов

Класс представляет собой составной тип, состоящий из полей (переменных), методов (процедур и функций) и свойств. Переменные типа класс называются объектами или экземплярами класса.

Описание класса имеет вид:

type
имя класса=class
описания полей
объявления или описания методов и описания свойств
end;

После слова class в скобках может быть указано имя класса-предка (см. Наследование), а также через запятую список поддерживаемых интерфейсов.

Перед словом class может быть указано ключевое слово final – в этом случае от класса запрещено наследовать.

Все описания и объявления внутри класса образуют тело класса. Поля описываются по тем же правилам, что и поля в записях (см. Записи). Инициализаторы полей описаны здесь. Поля и методы образуют интерфейс класса.

В отличие от Object Pascal, тела методов могут описываться как внутри, так и вне класса. Описание методов идентично описанию обычных подпрограмм. Объявление метода является заголовком подпрограммы, которая должна быть описана либо внутри, либо позднее вне тела класса. При описании вне класса имя метода должно предваряться именем класса с последующей точкой.

Например:

type
Person =class
private

nm: string;
ag: integer;
public
constructor Create(name: string; age: integer);
procedure Print;
begin
writeln('Имя: ',nm,' Возраст: ',ag);
end;
procedure NextYear;
begin
Inc(ag);
end;
end;

constructor Person.Create(name: string; age: integer);
begin
nm := name;
ag := age;
end;

Здесь конструктор Create объявлен в классе, а определен вне класса, а методы Print и NextYear определены внутри класса. При определении метода вне класса его имя предваряется именем класса с последующей точкой. При определении метода внутри класса он не должен содержать вложенные описания подпрограмм ввиду синтаксической неоднозначности. Объявление метода не может следовать за определением этого же метода в теле класса.

Обычно только небольшие методы определяются внутри класса. Это делается для того чтобы интерфейс класса был обозримым.

Каждый объект содержит копии всех полей, определенных в его классе, и может пользоваться всеми его методами.

В языке Object Pascal реализована ссылочная модель объектов. Это значит, что переменная типа класс хранит в действительности указатель на объект. Однако, при обращении к полям, методам или свойствам объекта разыменование такого указателя не требуется; указывается имя объекта и затем, после разделителя-точки, указывается имя поля, метода или свойства:

var p: Person := new Person('Иванов',20);
p.Print;
p.NextYear;
p.Print;

Как и другие указатели, переменная типа класс может хранить значение nil:

p :=nil;
...
if p =nil then ...

Несколько переменных типа класс могут ссылаться на один объект и совместно модифицировать его:

var p1,p2: Person;
...
p1 := new Person('Петров',20);
p2 := p1;
p1.IncAge;
p2.Print; // Имя: Петров Возраст: 21

Локальные определения классов (т.е. определения в процедурах и функциях) запрещены.

Видимость членов класса

Каждое поле, метод или свойство класса имеет атрибут видимости. В 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;
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;
public
constructor Create(xx,yy: integer);
begin
x := xx;
y := yy;
end;
constructor Create;
begin
end;
end;

В данном примере код x:=1 вставляется в начало каждого конструктора.

Конструкторы

Объекты создаются с помощью специальных методов, называемых конструкторами.

Конструктор представляет собой функцию, создающую объект в динамической памяти, инициализирующую его поля и возвращающую указатель на созданный объект. Этот указатель обычно сразу присваивается переменной типа класс. При описании конструктора вместо служебного слова 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;



Поделиться:


Последнее изменение этой страницы: 2024-06-27; просмотров: 3; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.117.101.7 (0.006 с.)