Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Билет№16.docx
Скачиваний:
50
Добавлен:
15.09.2019
Размер:
38 Кб
Скачать
☆

Пример программы c записью Паскаля

program primer 2 ; type anketa=record    fio: string[45];    dat_r: string[8];    adres: string[50];    curs: 1..5;    grupp: string[3] end; var student: array [1..100] of anketa;    I: integer; begin    {последовательно вводим каждую запись}    for I:=1 to 100 do    begin       writeln (‘введите сведения о’, I , ‘-м студенте’);       writeln (‘введите фамилию, имя и отчество’);       readln (student[I].fio);       writeln (‘введите дату рождения’);       readln (student[I].dat_r);       writeln (‘введите адрес’);       readln(student[I].adres);       writeln (‘введите курс’);       readln(student[I].curs);       writeln (‘введите группу’);       readln (student[I].grupp);    end;    writeln (‘ввод закончен’);    writeln ;    {просматриваем массив записей и выбираем только студентов 2-го курса }    for I:=1 to 100 do       if student[I].curs=2 then          writeln(‘ фамилия студента : ’, student[I].fio); end.

Оператор присоединения или как избавиться от префикса

Префикс – обязательная предшествующая часть составного идентификатора для имен полей в структуре типа запись Паскаля. Очень часто у программиста возникает желание не указывать префикс в имени полей, например, когда идет постоянное использование одних и тех же записей. В языке Паскаль предусмотрена такая возможность, реализуемая при помощи оператора присоединения, который в общем виде выглядит так:

with <имя_записи> do <действие с полем записи>;

Следует обратить внимание на то, что после служебного слова do может стоять только один оператор, но он может быть составным (любая последовательность операторов, заключенная в операторные скобки begin end ).

Например, фрагмент из предыдущей программы с использованием оператора присоединения будет выглядеть так:

Пример фрагмента программы c записью и префиксом Паскаля

for I:=1 to 100 do    with student[I] do    begin       writeln (‘введите сведения о’, I , ‘-м студенте’);       writeln (‘введите фамилию, имя и отчество’);       readln (fio);       writeln (‘введите дату рождения’);       readln (dat_r);       writeln (‘введите адрес’);       readln(adres);       writeln (‘введите курс’);       readln(curs);       writeln (‘введите группу’);       readln (grupp);    end;

2. Опис класу. Створення та вилучення об’єктів в Delphi.

Для создания классов в Object Pascal введена конструкция class:

Type    TmyClassA = class(имя класса-родителя)    End;

или

   TmyClassB = class    End;

"Так просто?" - скажете вы. Да, действительно просто - мы создали новый тип данных - класс TmyClassA (TmyClassB). И хотя мы еще ничего не сказали о том, что это за класс объектов, как будут вести себя объекты этого класса, какие они будет иметь свойства и многое другое, это все же настоящий класс объектов, который умеет уже очень многое!

Дело в том, что в Object Pascal все классы наследуются от базового класса TObject, который представляет из себя корень всей будущей иерархии классов, эдакий "первокирпичик". Этот "первокирпичик" умеет создавать свои экземпляры, уничтожать их, давать информацию о своем имени, имеет диспетчер сообщений и еще массу полезных функций, без которых не может существовать ни один класс. Если в заголовке класса не указан "родитель", то класс просто наследуется от TObject. Т.е. описание класса TmyClassB в данном случае равносильно следующей конструкции:

Type    TmyClassB = class(TObject)    End;

Попробуем теперь наш класс в действии. Но для начала следует подготовить плацдарм для боевых действий.

Запускаем Delphi, создаем новый проект (File -> New application). Затем убираем из проекта модуль Unit1 (Project -> Remove from project, выбираем Unit1 и нажимаем OK). В проекте остается только файл project.dpr. Стираем весь текст и оставляем только следующие строки:

Program ClassTest; {$AppType Console} Uses Windows; {$R *.RES} Begin End.

Все готово. Обратите внимание на 2-ю строку: {$AppType Console} . Это - команда компилятору собрать консольное приложение, т.е. приложение, работающее в текстовом режиме, подобно старым DOS-программам, написанным на Turbo Pascal. При этом программа остается полноценным Win32-приложением. Этого же результата можно добиться, открыв Опции проекта (Project -> Options...) и на вкладке Linker поставить галочку в пункте Generate console application. Таким образом мы на время избавили себя от необходимости изучения графического интерфейса Windows и получили простую возможность вывести результаты нашей работы на дисплей.

Ну а теперь приступим к испытаниям. Описание класса подобно проекту автомобиля, по которому на заводе собирают готовые экземпляры автомобилей. На проекте ездить нельзя :), а вот на автомобиле, собранном по этому проекту - пожалуйста. Точно так же следует поступить и нам:

Type    TmyClassA = class(TObject)    End;    TmyClassB = class    End; Var    ObjA: TmyClassA; { Описание переменной типа TmyClassA }    ObjB: TmyClassB; { Описание переменной типа TmyClassB } Begin    ObjA := TmyClassA.Create;    ObjB := TmyClassB.Create;

Мы создали экземпляры классов TmyClassA и TmyClassB (или собственно объекты) при помощи конструктора Create. Вообще каждый класс имеет конструктор (один или несколько) и деструктор. Цель конструктора - создание экземпляра (объекта) указанного класса. Ну а цель деструктора, как вы догадались - уничтожение объекта, надобность в котором отпала. В данном случае мы воспользовались конструкторами, унаследованными обоими классами от базового класса TObject. Конструктор класса создает объект в динамической памяти и возвращает ссылку на него, которую мы помещаем в переменную ObjА (ObjB).

У каждого класса есть имя и родительский класс, которые можно получить, вызвав методы ClassName (ИмяКласса) и ClassParent (РодительскийКласс):

Writeln('Class name:',objA.Classname, ' ',     'Parent:',objA.ClassParent.ClassName); Writeln('Class name:',objB.Classname, ' ',     'Parent:',objB.ClassParent.ClassName); readln;

Как мы видим, оба класса имеют "родителя" - TObject. Естественно, возникает вопрос, а каким образом мы можем узнать, в каких "родственных отношениях" находятся созданные объекты? Это можно узнать несколькими способами.

  1. при помощи методов ClassType (ТипКласса) и InheritsFrom (УнаследованОт):

Writeln('Is the ObjA instance of TmyClassA?',     ObjA.ClassType = TmyClassA); Writeln('Is the ObjA instance of TmyClassB?',     ObjA.ClassType = TmyClassB); Writeln('Is the ObjA instance of TObject?',     ObjA.ClassType = TObject); Writeln('Is the ObjA descendant of TObject?',     ObjA.InheritsFrom(TObject)); Writeln('Is the ObjA descendant of TmyClassB?',     ObjA.InheritsFrom(TmyClassB));

  1. при помощи оператора is:

Writeln('Is the ObjA instance of myClassA?',     ObjA is TmyClassA); Writeln('Is the ObjA descendant of TObject?',     ObjA is TObject);

Следует отметить, что выражение:

Writeln('Is the ObjA instance of myClassB?',     ObjA is TmyClassB);

будет отметено компилятором еще во время компиляции, т.к. ObjA действительно не может быть экземпляром класса TmyClassB. Зато возможна следующая ситуация:

var    Obj1, Obj2: TObject; begin    Obj1 := TmyClassA.Create;    Obj2 := TmyClassB.Create;

Мы описали две переменных типа TObject, в которые затем поместили ссылки на созданные экземпляры классов TmyClassA и TmyClassB. Да-да, и такая ситуация возможна! Представьте себе две коробки, на которых написано - "Яблоки". В одну мы положим антоновку, а в другую - белый налив. И это будет вполне естественно. А вот положить сливы в коробку из-под яблок будет несколько нечестно :). В таком случае мы можем не знать, какие яблоки лежат в коробках, но мы точно знаем, что лежат там именно яблоки.

В этой ситуации компилятор спокойно "переварит" приведенный текст:

Writeln('Is the Obj1 instance of myClassA?',    Obj1 is TmyClassA); Writeln('Is the Obj1 descendant of TObject?',    Obj1 is TObject); Writeln('Is the Obj1 instance of myClassB?',    Obj1 is TmyClassB);

так как реальный тип объекта, содержащийся в Obj1, еще не известен, но точно известно, что это будет наследник от TObject. A т.к. TmyClassB тоже унаследован от TObject, то последняя строчка вполне корректна.

Уфф! Наработались? Теперь надо за собой убрать.

ObjA.Destroy; ObjB.Destroy;

Destroy - это деструктор. Деструктор производит все завершающие действия по корректному завершению работы объекта и затем уничтожает его. После вызова деструктора ссылка, лежащая в переменной ObjA (ObjB) становится недействительной, и ее использование может привести к непредсказуемым результатам!

Но непосредственное использование деструктора в Object Pascal не рекомендуется. Более правильно для уничтожения объекта использовать метод free:

ObjA.free; ObjB.free;

Free проверяет, не является ли ссылка на объект пустой (nil), и если ссылка не пуста, вызывает деструктор.

Но пока классы TmyClassA и TmyClassB остаются вещью в себе. Чтобы экземпляры наших новых классов обрели хоть какой-то смысл, надо наполнить их содержимым. Этим мы и займемся далее.