«Test»). Откомпилируйте ваше приложение (команда Project | Make All Projects). Если все прошло без ошибок, выделите на форме ваш компонент и взгляните на его свойства в Инспекторе объектов. Вы найдете там добавленные вами свойства EnableNum и EnableLet. Оба свойства имеют по умолчанию заданные в конструкторе значения true. Попробуйте изменить оба значения на false. Это вам не удастся сделать, так как сработают написанные вами методы записи.
Свойство Modified в Инспекторе объектов вы не увидите, так как это свойство может использоваться только во время выполнения.
3.Задания к лабораторной работе.
1.Для определения иерархии классов связать отношением наследования классы, приведенные в приложении (для заданного варианта). Из перечисленных классов выбрать один, который будет стоять во главе иерархии. Это абстрактный класс.
2.Определить в классах все необходимые конструкторы и деструктор.
3.Компонентные данные класса специфицировать как protected.
4.Пример определения статических компонентов:
static person* begin; // указатель на начало списка static void print(void); // просмотр списка
5.Статическую компоненту-данное инициализировать вне определения класса, в глобальной области.
6.Для добавления объекта в список предусмотреть метод класса, т.е. объект сам добавляет себя в список. Например, a.Add() − объект a добавляет себя в список.
Включение объекта в список можно выполнять при создании объекта, т.е. поместить операторы включения в конструктор. В случае иерархии классов, включение объекта в список должен выполнять только конструктор базового класса. Вы должны продемонстрировать оба этих способа.
7.Список просматривать путем вызова виртуального метода Show каждого объекта.
8.Статический метод просмотра списка вызывать не через объект, а через класс.
9.Определение классов, их реализацию, демонстрационную программу поместить в отдельные файлы.
Варианты классов:
1) студент, преподаватель, персона, зав.кафедрой; 2) служащий, персона, рабочий, инженер; 3) рабочий, кадры, инженер, администрация; 4) деталь, механизм, изделие, узел;
5) организация, страховая компания, судостроительная компания, завод;
6) журнал, книга, печатное издание, учебник; 7) тест, экзамен, выпускной экзамен, испытание; 8) место, область, город, мегаполис; 9) игрушка, продукт, товар, молочный продукт;
10) квитанция, накладная, документ, чек; 11) автомобиль, поезд, транспортное средство, экспресс;
12)двигатель, двигатель внутреннего сгорания, дизель, турбореактивный двигатель;
13)республика, монархия, королевство, государство;
14)млекопитающие, парнокопытные, птицы, животное;
15)корабль, пароход, парусник, корвет.
4. Контрольные вопросы.
1.Что такое иерархия классов? Приведите пример иерархии. 2. Как создать класс?
3.Как создается экземпляр класса?
4.Что такое наследование?
5.Что такое полиморфизм?
Лабораторная работа №4. Создание методов и событий.
1.Цель лабораторной работы.
Целью лабораторной работы является получение практических навыков разработки объектно-ориентированной программы, управляемой событиями.
2.Теоретический материал для домашнего изучения.
Методы включаются в открытый раздел класса — раздел public,
поскольку иначе их нельзя было бы использовать. Собственно один метод
— коиструктор TEditLetNum, вы уже написали. Теперь вам нужно написать метод Clear, очищающий содержимое окна редактирования и устанавливающий значение поля FModified равным false. Генерировать событие OnClear мы пока не будем. А поскольку базовый класс TEdit уже имеет метод Clear, очищающий текст, занесенный в окно редактирования,
то вы можете в вашем переопределенном методе вызвать наследуемый метод Clear и добавить задание значения FModified. Чтобы точно знать,
как выглядит объявление метода Clear в классе-предке, полезно обра-
титься к справке C++Builder и точно воспроизвести в вашем новом классе объявление переопределяемого метода. Это объявление в классе
TCustomEdit имеет вид:
virtual void __fastcall Clear(void);
Таким образом, объявление и реализация переопределенного метода
Clear может иметь вид:
class PACKAGE TEditLetNum : public TEdit
{
…
public:
…
virtual void __fastcall Clear(void);
…
};
…
void __fastcall TEditLetNum::Clear(void)
{
TEdit::Clear(); |
//Вызов родительского метода |
FModified = false; |
|
} |
|
Как видно из приведенного кода, для вызова родительского метода
достаточно просто указать явным образом класс (в нашем случае TEdit),
метод которого вызывается.
Впрочем, в данном случае вы могли бы и не обращаться к
родительскому методу, а просто очистить текст в окне:
void fastcall TEditLetNum::Clear{void)
{
Text = ―‖;
FModified = false;
}
Теперь запишем главную процедуру, ради которой мы и создавали свой компонент: процедуру, разрешающую или запрещающую ввод символов того или иного типа. Для этого нам надо анализировать вводимый пользователем символ. Это можно делать при обработке события OnKeyPress. Значит, нам надо переопределить стандартную функцию генерации (т.е. стандартный обработчик) в родительском компоненте TEdit. Стандартные обработчики имеют то же имя, что и события, но без префикса Он. То есть обработчик события OnKeyPress
имеет имя KeyPress. Передаваемые в стандартный обработчик параметры те же, что вы можете видеть в заготовке процедуры обработки события,
если щелкнете на этом событии в Инспекторе Объектов, но без параметра
Sender. Например, щелкнув в Инспекторе Объектов на событии
OnKeyPress любого компонента, вы увидите, что в процедуру обработки передаются параметры:
(TObject *Sender, char SKey)
Значит в создаваемом нами обработчике и при вызове родительского обработчика надо использовать только один параметр: char &Кеу.
Впрочем, поскольку вам надо будет точно воспроизвести объявление переопределяемой функции в классе-предке, обратитесь к справке
C++Builder. Вы увидите, что функция KeyPress наследуется из класса
TWinControl и объявлена в нем следующим образом:
DYNAMIC void __fastcall KeyPress(char &Key);
Это объявление надо в точности воспроизвести в своем классе-
наследнике. Например, если вы пропустите в объявлении спецификатор
DYNAMIC, вы получите при компиляции сообщение:
[С++ Error] EditLetNum.h(24): Е2113 Virtual function '__fastcall TEditLetNum::KeyPress(char &)' conflicts with base class 'TWinControl'
Его смысл заключается в том, что возник конфликт с функцией KeyPress,
объявленной в базовом классе TWinControl. В результате компиляция не будет завершена.
Таким образом, введение в модуль компонента требуемой нам функции может свестись к включению в раздел класса protected
приведенного выше объявления и написанию в файле модуля реализации функции:
void __fastcall TEditLetNum::KeyPress(char &Key)
{
Set <char, '0', '9'> Dig;
Dig << '0' << '1' << '2' << '3' << '4' << '5' << '6' << '7' << '8' << '9'; if ((! FEnableNum) && (Dig.Contains(Key)))
Key = 0;
if ((! FEnableLet) && !(Dig.Contains(Key))) Key = 0;