Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Классы в программных модулях



Классы очень удобно собирать в модули. При этом их описание помещается в секцию interface, а код методов — в секцию implementation. Создавая модули классов, нужно придерживаться следующих правил:

1. все классы, предназначенные для использования за пределами модуля, следует определять в секции interface;

2. описание классов, предназначенных для употребления внутри модуля, следует располагать в секции implementation;

3. если модуль B использует модуль A, то в модуле B можно определять классы, порожденные от классов модуля A.

Соберем рассмотренные ранее классы TTextReader, TDelimitedReader и TFixedReader в отдельный модуль ReadersUnit:

unit ReadersUnit;   interface   type TTextReader = class private // Поля FFile: TextFile; FItems: array of string; FActive: Boolean; // Методы procedure PutItem(Index: Integer; const Item: string); // Методы чтения и записи свойств procedure SetActive(const AActive: Boolean); function GetItemCount: Integer; function GetEndOfFile: Boolean; protected // Методы чтения и записи свойств function GetItem(Index: Integer): string; // Абстрактные методы function ParseLine(const Line: string): Integer; virtual; abstract; public // Конструкторы и деструкторы constructor Create(const FileName: string); destructor Destroy; override; // Методы function NextLine: Boolean; // Свойства property Active: Boolean read FActive write SetActive; property Items[Index: Integer]: string read GetItem; default; property ItemCount: Integer read GetItemCount; property EndOfFile: Boolean read GetEndOfFile; end;   TDelimitedReader = class(TTextReader) private // Поля FDelimiter: Char; protected // Методы function ParseLine(const Line: string): Integer; override; public // Конструкторы и деструкторы constructor Create(const FileName: string; const ADelimiter: Char = '; '); // Свойства property Delimiter: Char read FDelimiter; end;   TFixedReader = class(TTextReader) private // Поля FItemWidths: array of Integer; protected // Методы function ParseLine(const Line: string): Integer; override; public // Конструкторы и деструкторы constructor Create(const FileName: string; const AItemWidths: array of Integer); end;   TMyReader = class(TDelimitedReader) property FirstName: string index 0 read GetItem; property LastName: string index 1 read GetItem; property Phone: string index 2 read GetItem; end;   implementation   { TTextReader }   constructor TTextReader.Create(const FileName: string); begin inherited Create; AssignFile(FFile, FileName); FActive: = False; end;   destructor TTextReader.Destroy; begin Active: = False; inherited; end;   function TTextReader.GetEndOfFile: Boolean; begin Result: = Eof(FFile); end;   function TTextReader.GetItem(Index: Integer): string; begin Result: = FItems[Index]; end;   function TTextReader.GetItemCount: Integer; begin Result: = Length(FItems); end;   function TTextReader.NextLine: Boolean; var S: string; N: Integer; begin Result: = not EndOfFile; if Result then // Если не достигнут конец файла begin Readln(FFile, S); // Чтение очередной строки из файла N: = ParseLine(S); // Разбор считанной строки if N < > ItemCount then SetLength(FItems, N); // Отсечение массива (если необходимо) end; end;   procedure TTextReader.PutItem(Index: Integer; const Item: string); begin if Index > High(FItems) then // Если индекс выходит за границы массива, SetLength(FItems, Index + 1); // то увеличение размера массива FItems[Index]: = Item; // Установка соответствующего элемента end;   procedure TTextReader.SetActive(const AActive: Boolean); begin if Active < > AActive then // Если состояние изменяется begin if AActive then Reset(FFile) // Открытие файла else CloseFile(FFile); // Закрытие файла FActive: = AActive; // Сохранение состояния в поле end; end;   { TDelimitedReader }   constructor TDelimitedReader.Create(const FileName: string; const ADelimiter: Char = '; '); begin inherited Create(FileName); FDelimiter: = ADelimiter; end;   function TDelimitedReader.ParseLine(const Line: string): Integer; var S: string; P: Integer; begin S: = Line; Result: = 0; repeat P: = Pos(Delimiter, S); // Поиск разделителя if P = 0 then // Если разделитель не найден, то считается, что P: = Length(S) + 1; // разделитель находится за последним символом PutItem(Result, Copy(S, 1, P - 1)); // Установка элемента Delete(S, 1, P); // Удаление элемента из строки Result: = Result + 1; // Переход к следующему элементу until S = ''; // Пока в строке есть символы end;   { TFixedReader }   constructor TFixedReader.Create(const FileName: string; const AItemWidths: array of Integer); var I: Integer; begin inherited Create(FileName); // Копирование AItemWidths в FItemWidths SetLength(FItemWidths, Length(AItemWidths)); for I: = 0 to High(AItemWidths) do FItemWidths[I]: = AItemWidths[I]; end;   function TFixedReader.ParseLine(const Line: string): Integer; var I, P: Integer; begin P: = 1; for I: = 0 to High(FItemWidths) do begin PutItem(I, Copy(Line, P, FItemWidths[I])); // Установка элемента P: = P + FItemWidths[I]; // Переход к следующему элементу end; Result: = Length(FItemWidths); // Количество элементов постоянно end;   end.

Как можно заметить, в описании классов присутствуют новые ключевые слова private, protected и public. С их помощью регулируется видимость частей класса для других модулей и основной программы. Назначение каждого ключевого слова поясняется ниже.

Разграничение доступа к атрибутам объектов

Программист может разграничить доступ к атрибутам своих объектов для других программистов (и себя самого) с помощью специальных ключевых слов: private, protected, public, published (последнее не используется в модуле ReadersUnit).

Private. Все, что объявлено в секции private недоступно за пределами модуля. Секция private позволяет скрыть те поля и методы, которые относятся к так называемым особенностям реализации. Например, в этой секции класса TTextReader объявлены поля FFile, FActive и FItems, а также методы PutItem, SetActive, GetItemCount и GetEndOfFile.

Public. Поля, методы и свойства, объявленные в секции public не имеют никаких ограничений на использование, т.е. всегда видны за пределами модуля. Все, что помещается в секцию public, служит для манипуляций с объектами и составляет программный интерфейс класса. Например, в классе TTextReader в эту секцию помещены конструктор Create, метод NextLine, свойства Active, Items, ItemCount.

Protected. Поля, методы и свойства, объявленные в секции protected, видны за пределами модуля только потомкам данного класса; остальным частям программы они не видны. Так же как и private, директива protected позволяет скрыть особенности реализации класса, но в отличие от нее разрешает другим программистам порождать новые классы и обращаться к полям, методам и свойствам, которые составляют так называемый интерфейс разработчика. В эту секцию обычно помещаются виртуальные методы. Примером такого метода является ParseLine.

Published. Устанавливает правила видимости те же, что и директива public. Особенность состоит в том, что для элементов, помещенных в секцию published, компилятор генерирует информацию о типах этих элементов. Эта информация доступна во время выполнения программы, что позволяет превращать объекты в компоненты визуальной среды разработки. Секцию published разрешено использовать только тогда, когда для самого класса или его предка включена директива компилятора $TYPEINFO.

Перечисленные секции могут чередоваться в объявлении класса в произвольном порядке, однако в пределах секции сначала следует описание полей, а потом методов и свойств. Если в определении класса нет ключевых слов private, protected, public и published, то для обычных классов всем полям, методам и свойствам приписывается атрибут видимости public, а для тех классов, которые порождены от классов библиотеки VCL, — атрибут видимости published.

Внутри модуля никакие ограничения на доступ к атрибутам классов, реализованных в этом же модуле, не действуют. Кстати, это отличается от соглашений, принятых в некоторых других языках программирования, в частности в языке C++.


Поделиться:



Популярное:

Последнее изменение этой страницы: 2016-07-14; Просмотров: 397; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.016 с.)
Главная | Случайная страница | Обратная связь