ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 10.01.2024
Просмотров: 290
Скачиваний: 1
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
СОДЕРЖАНИЕ
ЛР 1. Операторы и выражения Delphi
Управление жизненным циклом объекта
Ограничение видимости членов класса
Особенности объявления методов
Принадлежность к родительскому контейнеру
Размещение и размеры элемента управления
Видимость и активность элемента управления
ЛР5. Обработка клавиатурных событий и событий мышки
, поэтому старайтесь объявлять множества разумного размера.
А теперь предложим несколько строк кода (листинг 2.2), демонстрирующих работу с множествами.
Листинг 2.2. Управление элементами множества
type TFlagsSet = set of (Flag1, Flag2, Flag3);
...
var Flags : TFlagsSet;
begin
Flags:=[]; //[0,0,0] - полностью очистили множество Flags:=[TFlagsSet.Flag1]; //[1,0,0] - включили 1-й элемент Flags:=Flags+[TFlagsSet.Flag3]; //[1,0,1]- добавили 3-й элемент Flags:=Flags-[TFlagsSet.Flag1]; //[0,0,1]- отключили 1-й элемент
Flags:=[TFlagsSet.Flag1, TFlagsSet.Flag2, TFlagsSet.Flag3];
{[1,1,1] — включили все три элемента}
...
end;
Для проверки, включен ли элемент во множество, применяют оператор in.
If (Flag2 in Flags) then <операция1> else <операция2>;
Множества Delphi поддерживают все стандартные операции, применимые к математическим множествам. В первую очередь это операции сложения и вычитания.
[Flag1, Flag2]+[Flag3] = [Flag1, Flag2, Flag3] [Flag1, Flag2, Flag3]-[Flag2, Flag3] = [Flag1]
Еще одна очень важная для множеств операция пересечения позволяет вычислить общие для двух множеств элементы:
[Flag1, Flag2]*[ Flag2, Flag3] = [Flag2]
Если определены два однотипных множества, то между ними вполне допустимы операции сравнения (<=, >=, =, <>). В операциях сравнения множество X меньше или равно множеству Y (выражение (X<=Y)=True), если каждый элемент множества X является членом множества Y. Множество
X равно множеству Y (выражение (X=Y)=True) в случае, если все элементы множества X точно соответствуют элементам Y. Множество X неравно Y (выражение (X<>Y)=True), если хотя бы один элемент множества X отсутствует во множестве Y.
Запись (record) позволяет объединять несколько разнотипных полей в общую структуру. Идея построения составных структур появилась еще во времена языка Pascal и сразу очень понравилась разработчикам. В простейшей нотации запись современного языка Delphi ничем не отличается от аналогичной структуры старого доброго языка Pascal. Листинг 2.3 демонстрирует объявление записи, которое будет поддержано во всех, базирующихся на языке Pascal средах разработки.
Листинг 2.3. Пример работы с записью
type TDemoRecord=record //описание типа записи A: Byte; //поля записи
B: Integer;
C: Word;
D: Integer;
end;
var DemoRecord:TDemoRecord; //объявление переменной
begin
{присвоение полям записи значений} DemoRecord.A:=50;
DemoRecord.B:=0;
end.
Язык Delphi позволяет создавать упакованные записи, т. е. записи, в которых по возможности отсутствует выравнивание полей. Режим упаковки активируется у записей, помеченных инструкцией packed (листинг 2.4).
Листинг 2.4. Упаковка записи
type TDemoRecord3 = packed record
B,D: Integer;
C: Word;
A: Byte;
end;
Если провести анализ нового варианта структуры с помощью функции SizeOf(), то мы, наконец, получим так долго ожидаемый размер в 11 байт. Однако достигнутая экономия при хранении данных имеет обратную сторону — несколько увеличивается время на доступ к полям структуры, особенно если они начинаются не с начала 32-битовой области и переходят через границу этой области. Поэтому при проектировании упакованных записей рекомендуется сначала размещать поля, размер которых кратен 4 байтам (например: Integer и Cardinal), а поля остальных типов смещать к концу структуры.
В реальной жизни один и тот же объект может иметь несколько способов описания. Одна и та же точка на поверхности земного шара идентифицируется географическими или прямоугольными координатами, вес предмета
может быть измерен в граммах или фунтах, расстояние до объекта можно указать в километрах или в милях.
Создатели языка Delphi позаботились о том, чтобы используемые в наших программах структуры обладали максимальной гибкостью. Именно поэтому в состав полей записи допускается включать вариантное поле (листинг 2.5).
Листинг 2.5. Запись с вариантным полем
type TDimensionMode=(kilometer,mile);
type TDistance=record ObjectName:string[30];
case DimensionMode:TDimensionMode of
kilometer : (km :real); mile : (ml :real);
end;
Запись TDistance позволяет сохранить расстояние до объекта в километрах или милях. Для того чтобы указать, к какому из вариантов относится вводимое значение, надо воспользоваться полем признакаDimensionMode и передать в него значение kilometer или mile.
Современные версии Delphi способны превратить обычную запись (всю жизнь до этого специализирующуюся лишь на хранении данных) в комплексную структуру с набором возможностей, очень близким к функционалу класса. Как следствие, "простушка" запись из обычного хранилища разнотипных полей превращается в интеллектуальную систему обслуживания данных. Безусловно, степень разумности такой записи определяется глубиной заложенного в структуру программного кода. В листинге 2.6 предложен пример объявления записи с расширенными возможностями. Запись TStudent предназначена не только для хранения фамилии, имени и даты рождения студента, ко всему прочему запись способна вычислить возраст студента.
Листинг 2.6. Запись с расширенными возможностями
Uses SysUtils, DateUtils;
...
type TStudent=record
private //секция частных объявлений
function
GetAge: Integer; //метод записи
public //секция публичных объявлений SName,FName:string[15]; //фамилия и имя
BDate:TDate; //дата рождения
property Age:integer read GetAge; //свойство записи — возраст
end;
{ TStudent }
function TStudent.GetAge: integer; //реализация метода
begin
{узнаем разницу между текущей датой и датой рождения} Result:=YearsBetween(Now, BDate);
{для работы функции YearsBetween необходимо подключить модуль DateUtils}
end;
По сравнению классическим способом описания записи наш пример (см. листинг 2.7) содержит много необычного:
Безусловно, даже усовершенствованная запись не способна заменить класс (записи не поддерживают наследование, у них не могут быть объявлены виртуальные и динамические методы, запись не может обладать деструктором), но такая задача перед программистами Embarcadero и не ставилась. Новый синтаксис записей просто предоставляет программисту Delphi существенно улучшенный инструмент для разработки программ.
Примечание
Начиная с Delphi 2009, при описании типа записи допускается задавать поля с заранее неопределенным (обобщенным) типом данных.
А теперь предложим несколько строк кода (листинг 2.2), демонстрирующих работу с множествами.
Листинг 2.2. Управление элементами множества
type TFlagsSet = set of (Flag1, Flag2, Flag3);
...
var Flags : TFlagsSet;
begin
Flags:=[]; //[0,0,0] - полностью очистили множество Flags:=[TFlagsSet.Flag1]; //[1,0,0] - включили 1-й элемент Flags:=Flags+[TFlagsSet.Flag3]; //[1,0,1]- добавили 3-й элемент Flags:=Flags-[TFlagsSet.Flag1]; //[0,0,1]- отключили 1-й элемент
Flags:=[TFlagsSet.Flag1, TFlagsSet.Flag2, TFlagsSet.Flag3];
{[1,1,1] — включили все три элемента}
...
end;
Для проверки, включен ли элемент во множество, применяют оператор in.
If (Flag2 in Flags) then <операция1> else <операция2>;
Множества Delphi поддерживают все стандартные операции, применимые к математическим множествам. В первую очередь это операции сложения и вычитания.
[Flag1, Flag2]+[Flag3] = [Flag1, Flag2, Flag3] [Flag1, Flag2, Flag3]-[Flag2, Flag3] = [Flag1]
Еще одна очень важная для множеств операция пересечения позволяет вычислить общие для двух множеств элементы:
[Flag1, Flag2]*[ Flag2, Flag3] = [Flag2]
Если определены два однотипных множества, то между ними вполне допустимы операции сравнения (<=, >=, =, <>). В операциях сравнения множество X меньше или равно множеству Y (выражение (X<=Y)=True), если каждый элемент множества X является членом множества Y. Множество
X равно множеству Y (выражение (X=Y)=True) в случае, если все элементы множества X точно соответствуют элементам Y. Множество X неравно Y (выражение (X<>Y)=True), если хотя бы один элемент множества X отсутствует во множестве Y.
Записи
Запись (record) позволяет объединять несколько разнотипных полей в общую структуру. Идея построения составных структур появилась еще во времена языка Pascal и сразу очень понравилась разработчикам. В простейшей нотации запись современного языка Delphi ничем не отличается от аналогичной структуры старого доброго языка Pascal. Листинг 2.3 демонстрирует объявление записи, которое будет поддержано во всех, базирующихся на языке Pascal средах разработки.
Листинг 2.3. Пример работы с записью
type TDemoRecord=record //описание типа записи A: Byte; //поля записи
B: Integer;
C: Word;
D: Integer;
end;
var DemoRecord:TDemoRecord; //объявление переменной
begin
{присвоение полям записи значений} DemoRecord.A:=50;
DemoRecord.B:=0;
end.
Язык Delphi позволяет создавать упакованные записи, т. е. записи, в которых по возможности отсутствует выравнивание полей. Режим упаковки активируется у записей, помеченных инструкцией packed (листинг 2.4).
Листинг 2.4. Упаковка записи
type TDemoRecord3 = packed record
B,D: Integer;
C: Word;
A: Byte;
end;
Если провести анализ нового варианта структуры с помощью функции SizeOf(), то мы, наконец, получим так долго ожидаемый размер в 11 байт. Однако достигнутая экономия при хранении данных имеет обратную сторону — несколько увеличивается время на доступ к полям структуры, особенно если они начинаются не с начала 32-битовой области и переходят через границу этой области. Поэтому при проектировании упакованных записей рекомендуется сначала размещать поля, размер которых кратен 4 байтам (например: Integer и Cardinal), а поля остальных типов смещать к концу структуры.
Вариантные поля
В реальной жизни один и тот же объект может иметь несколько способов описания. Одна и та же точка на поверхности земного шара идентифицируется географическими или прямоугольными координатами, вес предмета
может быть измерен в граммах или фунтах, расстояние до объекта можно указать в километрах или в милях.
Создатели языка Delphi позаботились о том, чтобы используемые в наших программах структуры обладали максимальной гибкостью. Именно поэтому в состав полей записи допускается включать вариантное поле (листинг 2.5).
Листинг 2.5. Запись с вариантным полем
type TDimensionMode=(kilometer,mile);
type TDistance=record ObjectName:string[30];
case DimensionMode:TDimensionMode of
kilometer : (km :real); mile : (ml :real);
end;
Запись TDistance позволяет сохранить расстояние до объекта в километрах или милях. Для того чтобы указать, к какому из вариантов относится вводимое значение, надо воспользоваться полем признакаDimensionMode и передать в него значение kilometer или mile.
Усовершенствованная запись
Современные версии Delphi способны превратить обычную запись (всю жизнь до этого специализирующуюся лишь на хранении данных) в комплексную структуру с набором возможностей, очень близким к функционалу класса. Как следствие, "простушка" запись из обычного хранилища разнотипных полей превращается в интеллектуальную систему обслуживания данных. Безусловно, степень разумности такой записи определяется глубиной заложенного в структуру программного кода. В листинге 2.6 предложен пример объявления записи с расширенными возможностями. Запись TStudent предназначена не только для хранения фамилии, имени и даты рождения студента, ко всему прочему запись способна вычислить возраст студента.
Листинг 2.6. Запись с расширенными возможностями
Uses SysUtils, DateUtils;
...
type TStudent=record
private //секция частных объявлений
function
GetAge: Integer; //метод записи
public //секция публичных объявлений SName,FName:string[15]; //фамилия и имя
BDate:TDate; //дата рождения
property Age:integer read GetAge; //свойство записи — возраст
end;
{ TStudent }
function TStudent.GetAge: integer; //реализация метода
begin
{узнаем разницу между текущей датой и датой рождения} Result:=YearsBetween(Now, BDate);
{для работы функции YearsBetween необходимо подключить модуль DateUtils}
end;
По сравнению классическим способом описания записи наш пример (см. листинг 2.7) содержит много необычного:
-
появились секции частных и публичных объявлений; -
запись приобрела право обладать методами; -
у записи могут быть свойства.
Безусловно, даже усовершенствованная запись не способна заменить класс (записи не поддерживают наследование, у них не могут быть объявлены виртуальные и динамические методы, запись не может обладать деструктором), но такая задача перед программистами Embarcadero и не ставилась. Новый синтаксис записей просто предоставляет программисту Delphi существенно улучшенный инструмент для разработки программ.
Примечание
Начиная с Delphi 2009, при описании типа записи допускается задавать поля с заранее неопределенным (обобщенным) типом данных.