Современные технологии программирования
Конспект лекций
назад | содержание

Лекция 13. Уровни доступа

Содержание

Введение *

Изучаемые вопросы: *

Области видимости (уровни доступа) *

Выводы *

Контрольные вопросы *

Источники дополнительных сведений *

 

Введение

    Изучаемые вопросы:

уровни доступа private, public, protected, published.

Переопределение свойств.

Области видимости (уровни доступа)

Пользователи класса могут использовать класс по-разному. Одни будут пользоваться только объектами класса. Другие будут создавать на основе используемого класса свои классы. Организация областей видимости класса позволяет разделить пользователей класса на группы, которые имеют разные возможности использования класса.

При описании нового класса важен разумный компромисс. С одной стороны, требуется скрыть от других методы и поля, представляющие собой внутреннее устройство класса (для этого и придуманы свойства). Маловажные детали на уровне пользователя будут бесполезны и только помешают целостности восприятия.

С другой стороны, если слишком ограничить разработчика, который будет порождать классы-потомки, и не обеспечить ему достаточный набор инструментальных средств и свободу действий, то он не станет использовать ваш класс.

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

Области видимости, определяемые первыми тремя директивами таковы:

Пример. Области видимости.

program PAccess;

{$APPTYPE CONSOLE}

uses

SysUtils,

Mod1 in 'Mod1.pas',

Mod2 in 'Mod2.pas',

Mod3 in 'Mod3.pas',

var

a: TMyClass1;

begin

a:= TMyClass1.Create;

// a.Field; //неверно: свойство находится вне области видимости

// Mod2.a.Field;//неверно: свойство находится вне области видимости

// Mod2.b.Field;//неверно: свойство находится вне области видимости

writeln(Mod3.a.Field);

readln;

end.

//-------------------------------------------------------------------------

unit Mod1;

interface

Type

TMyClass1 = class

private

FField: Real;

protected

property Field: Real read FField write FField;

procedure M;

end;

var a: TMyClass1;

implementation

procedure TMyClass1.M;

begin

end;

//Свойство с уровнем protected доступно в подпрограммах модуля, где

//описан класс

procedure Print(a: TMyClass1);

begin

writeln('Mod1, a: ',a.ClassName,' FField = ',a.Field);

end;

initialization

a:= TMyClass1.Create;

a.FField:= 1; //Поле с уровнем private доступно в модуле, где описан класс

writeln(a.Field);

Print(a); //Свойство с уровнем protected доступно в модуле, где

//описан класс

finalization

a.Free;

end.

//-------------------------------------------------------------------------

unit Mod2;

interface

uses Mod1;

Type

TMyClass2 = class(TMyClass1)

end;

var

a: TMyClass1;

b: TMyClass2;

implementation

procedure Print(a: TMyClass2);

begin

writeln('Mod1, a: ',a.ClassName,' FField = ',a.Field);

end;

initialization

//-------------------------------------------------------------------

b:= TMyClass2.Create;

//b.FField := 3; неверно: поле находится вне области видимости

b.Field:= 2;

Print(b);

//-------------------------------------------------------------------

a:= TMyClass1.Create;

//a.FField:= 5; неверно: поле находится вне области видимости

//a.Field =: 3; неверно: свойство находится вне области видимости

finalization

a.Free;

b.Free;

end.

//-------------------------------------------------------------------

unit Mod3;

interface

uses Mod2;

Type

TMyClass3 = class(TMyClass2)

public

property Field;

end;

var

a: TMyClass3;

implementation

procedure Print(a: TMyClass3);

begin

writeln('Mod1, a: ',a.ClassName,' FField = ',a.Field);

end;

initialization

a:= TMyClass3.Create;

a.Field:= 3;

Print(a);

finalization

a.Free;

end.

 

Область видимости, определяемая директивой published, имеет особое значение для интерфейса визуального проектирования Delphi. В этой секции могут быть собраны те свойства объекта, которые будут видны не только во время выполнения приложения, но и из среды разработки. Публиковать можно свойства большинства типов, за исключением типа real, свойства типа массив и некоторых других. Все свойства компонентов, доступные через Инспектор объектов, являются их опубликованными свойствами. Во время выполнения такие свойства общедоступны, как и public.

Три области видимости – private, protected, public -- как бы упорядочены по возрастанию видимости элементов класса. В классах потомках можно повысить видимость свойств, но не понизить её. При описании дочернего класса можно переносить свойства из одной сферы видимости в другую, не переписывая их заново и даже не описывая, -- достаточно упомянуть о нём в другом месте.

type

TFClass = class

private

FNumber: Integer;

protected

property Number: Integer read FNumber;

end;

TSClass = class(TFClass)

published

property Number;

end;

Если какое-либо свойство объекта из состава VCL принадлежит к области private, вернуть его в public невозможно. У многих компонентов (например, TEdit) есть предок (в данном случае TCustomEdit), который отличается только отсутствием опубликованных свойств. Так что, если вы хотите создать новый редактирующий компонент, порождайте его на базе TCustomEdit и публикуйте только те свойства, которые считаете нужными. Разумеется, если вы поместили свойство в область private, “достать” его оттуда в потомках возможности уже нет.

Пример использования раздела с уровнем доступа protected.

unit ULength;

interface

uses SysUtils;

const d = 2.54;

type

TLength = class

private

FLen: real;//длина в сантиметрах

protected

function GetSmStr:string;

procedure PutSmStr(newA:string);

function GetDmStr:string;

procedure PutDmStr(newA:string);

function GetDm:real;

procedure PutDm(newA:real);

public

property SmStr:string read GetSmStr write PutSmStr;

property DmStr:string read GetDmStr write PutDmStr;

property Dm: real read GetDm write PutDm;

property Sm: real read FLen write FLen;

constructor create(l: real = 0);

end;

var

L : TLength;

implementation

constructor TLength.Create(l: real);

begin

Sm:= l;

end;

function TLength.GetDmStr:string;

begin

GetDmStr:= FloatToStr(FLen*d);

end;

procedure TLength.PutDmStr(newA:string);

begin

FLen:= StrToFloat(newa)/d

end;

function TLength.GetSmStr:string;

begin

GetSmStr:= FloatToStr(FLen);

end;

procedure TLength.PutSmStr(newA:string);

begin

FLen:= StrToFloat(newa)

end;

function TLength.GetDm:real;

begin

GetDm:= FLen/d;

end;

procedure TLength.PutDm(newA:real);

begin

FLen:= newa*d

end;

initialization

finalization

end.

unit UCircle;

interface

uses ULength;

type

TCircle = class(TLength)

property Radius: Real read GetDm write PutDm;

function SquareSm: Real;

function PerimetrSm: Real;

function SquareDm: Real;

function PerimetrDm: Real;

end;

var Circle: TCircle;

implementation

function TCircle.SquareSm;

begin

result:= pi * System.Sqr(Sm);

end;

function TCircle.SquareDm;

begin

result:= pi * System.Sqr(Dm);

end;

function TCircle.PerimetrSm;

begin

result:= 2 * pi * Sm;

end;

function TCircle.PerimetrDm;

begin

result:= 2 * pi * Dm;

end;

end.

 

Выводы

 

Контрольные вопросы

  1. Что такое класс?
  2. Как описывается класс?
  3. Что такое поле?
  4. Что такое метод?
  5. Что такое свойство?
  6. Как создаются объекты?
  7. Как уничтожаются объекты?
  8. Что содержит переменная объектового типа?
  9. Как распределяется память под объект
  10. Что такое RTTI класса?
  11. Что такое инкапсуляция?
  12. Какой класс является общим предком по умолчанию?

 

Источники дополнительных сведений

 

 

наверх


назад | содержание