Вспоминаю ООП delphi

Начинал я кодить на паскале aka pascal, потом были уроки на с++, обе среды были под досом, так что были и свои недостатки и плюсы…

Потом появился предмет визуальное программирование и delphi, его сразу все полюбили, да и вообще это одно из самых красивых и удобных средств разработки и очень легко в переходе с паскаля на него…

Ну а вообще мне надо повторить ООП, объектно-ориентированное программирование:

* Класс — определенный пользователем тип данных, который обладает внутренними данными и методами в форме процедур или функций и обычно описывает родовые признаки и способы поведения ряда очень похожих объектов.
Класс — это структура данных, состоящая из некоторого количества элементов: полей, методов, свойств.
Объект — является экземпляром класса.
Поля — содержат данные определенного типа.
Методы — это функции и процедуры, выполняющие определенные действия.
Свойства — это поля данных, которые влияют на поведение объекта. Они служат для описания объекта и отличаются от обычных полей тем, что присвоение им значений связано с вызовом методов.
Классы инкапсулируют (т.е. включают в себя) поля, методы и свойства; это их первая черта.

Пример класса, работающего с текстовыми файлами, блоки в которых имеют фиксированный размер…

type
TFixedReader = class
private
// Поля
FFile: TextFile;
FItems: array of string;
FActive: Boolean;
FItemWidths: array of Integer;
// Методы чтения и записи свойств
procedure SetActive(const AActive: Boolean);
function GetItemCount: Integer;
function GetEndOfFile: Boolean;
function GetItem(Index: Integer): string;
// Методы
procedure PutItem(Index: Integer; const Item: string);
function ParseLine(const Line: string): Integer;
function NextLine: Boolean;
// Конструкторы и деструкторы
constructor Create(const FileName: string;
const AItemWidths: array of Integer);
destructor Destroy; override;
// Свойства
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;

{ TFixedReader }

constructor TFixedReader.Create(const FileName: string;
const AItemWidths: array of Integer);
var
I: Integer;
begin
AssignFile(FFile, FileName);
FActive := False;
// Копирование AItemWidths в FItemWidths
SetLength(FItemWidths, Length(AItemWidths));
for I := 0 to High(AItemWidths) do
FItemWidths[I] := AItemWidths[I];
end;

destructor TFixedReader.Destroy;
begin
Active := False;
end;

function TFixedReader.GetEndOfFile: Boolean;
begin
Result := Eof(FFile);
end;

function TFixedReader.GetItem(Index: Integer): string;
begin
Result := FItems[Index];
end;

function TFixedReader.GetItemCount: Integer;
begin
Result := Length(FItems);
end;

function TFixedReader.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;

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;

procedure TFixedReader.PutItem(Index: Integer; const Item: string);
begin
if Index > High(FItems) then    // Если индекс выходит за границы массива,
SetLength(FItems, Index + 1); // то увеличение размера массива
FItems[Index] := Item;          // Установка соответствующего элемента
end;

procedure TFixedReader.SetActive(const AActive: Boolean);
begin
if Active <> AActive then // Если состояние изменяется
begin
if AActive then
Reset(FFile)          // Открытие файла
else
CloseFile(FFile);     // Закрытие файла
FActive := AActive;     // Сохранение состояния в поле
end;
end;

Впринципе, если Вы разбираетесь в Delphi то все понятно 🙂 особенно с комментариями то!

Следующая не менее важная черта классов — способность наследовать поля, методы и свойства других классов.

Как создать класс потомок данного? Все просто, после ключевого слова class в скобочках пишем родителя…

type
TDelimitedReader = class(TFixedReader)
FDelimiter: Char;
function ParseLine(const Line: string): Integer; override;
constructor Create(const FileName: string; const ADelimiter: Char = ';');
property Delimiter: Char read FDelimiter;
end;

Все просто 🙂 хотя гемор очевиден…

Если у классов 1 родитель, то каждый потомок в праве перекрывать (override) функции родителя, переписывая их своими функциями. Это нужно чтобы не переписывать функции родителя, потому как той или иной функцией пользуються все остальные потомки…

Виртуальные методы

ООП предлагает изящное решение этой проблемы — метод ParseLine всего-навсего объявляется виртуальным:

type
TTextReader = class
...
function ParseLine(const Line: string): Integer; virtual; //Виртуальный метод
...
end;

Разберемся с Public, Private, Protected — атрибуты видимости.

В разделе частных (private) объявлений размещаются поля данных и методы, недоступные за пределами модуля, содержащего объявление данного класса. Данные, описанные в этом разделе, могут обрабатываться только путем вызова методов внутри класса, а также внутри данного модуля. За пределами класса все его частные элементы неизвестны и считаются несуществующими.

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

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

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Я не робот.