Видимость членов класса и модификаторы доступа
Каждое поле, метод или свойство класса имеет модификатор (атрибут) доступа, задающий правила его видимости. В 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
constructorCreate(xx: integer)
begin
x := xx; // верно, т.к. внутри метода класса можно обращаться к его закрытому полю x
a := 0; // верно
end;
;
Следующий же код пусть располагается в другом модуле: type
B = class(A)
public
procedureprint;
begin
writeln(a); // верно, т.к. a - защищенное поле
writeln(x); // неверно, т.к. х - закрытое поле
end;
end;
...
varb1: 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;
constructorCreate(xx1,yy1,xx2,yy2: integer);
begin
x1 := xx1; x2 := xx2;
y1 := yy1; y2 := yy2;
end;
functionSquare: integer;
end;
functionRectangle.Square: integer;
begin
Result := abs(x2-x1) * abs(y2-y1);
end;
Обычно когда класс определяется в интерфейсной части модуля, то в интерфейсе класса производят лишь объявление методов, реализацию же методов класса дают в секции реализации модуля.
Методы делятся на классовые и экземплярные . Классовые методы в .NET называются статическими . Объявление классового метода начинается с ключевого слова class. Экземплярные методы можно вызывать только через переменную-объект класса. Классовые же методы не связаны с конкретным экземпляром класса; их следует вызывать в виде:
имя класса . имя метода ( параметры )
Внутри классового метода не может быть обращения к полям класса, а может быть только обращение к другим классовым методам. Напротив, экземплярный метод может вызывать классовый.
Например:
type
Rectangle = class
...
class procedureMove( varr: Rectangle; dx,dy: integer);
begin
r.x1 += dx; r.x2 += dx;
r.y1 += dy; r.y2 += dy;
end;
end;
...
varr := newRectangle(10,10,100,100);
Rectangle.Move(r,5,5);
По существу, классовые методы являются разновидностью глобальных подпрограмм, но находятся внутри класса, что подчеркивает, что они осуществляют действия, связанные именно с этим классом. Класс в этом случае выступает только в роли пространства имен.
Нередко создаются классы, целиком состоящие из классовых методов. Таков, например, класс System.Math, содержащий определения математических подпрограмм.
При создании объекта его поля инициализируются автоматически нулевыми значениями если они не инициализированы явно. Их инициализация может проводиться как в конструкторе, так и непосредственно при описании. Инициализация поля при описании приводит к тому, что код инициализации вставляется в начало ВСЕХ конструкторов.
Читать дальше