В терминах Паскаля, объект во многом схож с записью, которая является оболочкой для объединения нескольких связанных элементов под одним именем. Предположим, вы хотите разработать программу вывода платежной ведомости, печатающую отчет и показывающую, сколько нужно выплатить каждому служащему за рабочий день. Запись можно организовать следующим образом:
TEmployee = record Name: string[25]; Title: string[25]; Rate: Real; end;
Примечание: По соглашению все типы начинаются с буквы T. Вы также можете следовать этому правилу.
Здесь TEmployee является типом записи, т.е. шаблоном, используемым компилятором для создания переменных типа запись. Переменная типа TEmployee является экземпляром этого типа. Термин "экземпляр" будет вам нередко встречаться в Паскале. Он постоянно применяется теми, кто использует методы объектно-ориентированного программирования, поэтому будет хорошо, если вы начнете мыслить в терминах типов и экземпляров этих типов.
Вы можете оперировать с типом TEmployee двояко. Вы можете рассматривать поля Name, Title и Rate по отдельности, а когда о полях, как о работающих одновременно для описания конкретного рабочего, вы можете рассматривать их совокупность, как TEmployee.
Предположим, что на вашей фирме работает несколько типов рабочих. Одни из них имеют почасовую оплату, другие - оклад, третьи - тарифную ставку и так далее. Ваша программа должна учитывать все эти типы. Вы можете создать другой тип записи для каждого типа рабочего. Например, для получения данных о том, сколько должен получить рабочий с почасовой оплатой, нужно знать, сколько часов он отработал. Можно построить запись THourly вида:
THourly = record Name: string[25]; Title: string[25]; Rate: Real; end;
Вы можете также оказаться несколько догадливее и сохранить тип TEmployee путем создания поля типа TEmployee внутри типа THourly:
THourly = record Worker: TEmployee; Time: integer; end;
Такая конструкция работает, и программисты, работающие на Паскале, делают это постоянно. Единственное, чего этот метод не делает, так это то, что он заставляет вас думать о том, с чем вы работаете в вашем программном обеспечении. Вам следует задаться вопросом типа; "Чем почасовик отличается от дpугих pабочих?" Ответ прост: почасовик - это pабочий, котоpому платится за количество часов pаботы. Продумайте снова первую часть предложения; почасовик - это pабочий...
Теперь вы поняли!
Запись для pаботника-почасовика hourly должна иметь все записи, котоpые имеются в записи employee. Tип THourly является дочерним типом для типа TEmployee. THourly наследует все, что принадлежит TEmployee, и кроме того имеет кое-что новое, что делает THourly уникальным.
Этот процесс, с помощью которого один тип наследует характеристики другого типа, называется наследованием. Наследник называется порожденным (дочерним) типом, а тип, которому наследует дочерний тип, называется порождающим (родительским) типом.
Ранее известные типы записей Паскаля не могут наследовать. Однако Borland Pascal расширяет язык Паскаль для поддержки наследования. Одним из этих расширений является новая категория структуры данных, связанная с записями, но значительно более мощная. Типы данных в этой новой категории определяются с помощью нового зарезервированного слова object. Тип объекта может быть определен как полный, самостоятельный тип в манере описания записей Паскаля, но он может определяться и как потомок существующего типа объекта путем помещения порождающего (родительского) типа в скобки после зарезервированного слова object.
В приводимом здесь примере платежной ведомости два связанных типа объектов могли бы определяться следующим образом:
type TEmployee = object Name: string[25]; Title: string[25]; Rate : Real; end;
THourly = object(TEmployee) Time : Integer; end;
Примечание: Обратите внимание, что здесь использование скобок означает наследование.
Здесь TEmployee является родительским типом, а THourly - дочерним типом. Как вы увидите чуть позднее, этот процесс может продолжаться неопределенно долго. Вы можете определить дочерний тип THourly, дочерний к типу THourly тип и т.д. Большая часть конструирования объектно-ориентированных прикладных программ состоит в построении такой иерархии объектов, являющейся отражением генеалогического дерева объектов в приложениях.
Все возможные типы, наследующие тип TEmployee, называются дочерними типами типа TEmployee, тогда как THourly является непосредственным дочерним типом типа TEmployee. Наоборот, TEmployee является непосредственным родителем типа THourly. Тип объекта (в точности как подкаталог в DOS) может иметь любое число непосредственных дочерних типов, но в то же время только одного непосредственного родителя.
Как показали данные определения, объекты тесно связаны с записями. Новое зарезервированное слово object является наиболее очевидным различием, но как вы увидите позднее, имеется большое число других различий, некоторые из которых довольно тонкие.
Например, поля Name, Title и Rate в типе TEmployee не указаны явно в типе THourly, но в любом случае тип THourly содержит их благодаря свойству наследования. Вы можете говорить о величине Name типа THourly в точности так же, как о величине Name типа TEmployee.
Экземпляры объектных типов
Экземпляры объектных типов описываются в точности так же, как в Паскале описывается любая переменная, либо статическая, либо указатель, ссылающийся на размещенную в динамической памяти переменную:
type PHourly = ^THourly; var StatHourly: THourly; { готово } DynaHourly: PHourly; { перед использованием память должна выделяться с помощью New }
Поля объектов
Вы можете обратиться к полю объекта в точности так же, как к полю обычной записи, либо с помощью оператора with, либо путем уточнения имени с помощью точки. Например:
AnHourly.Rate := 9.45;
with AnHourly do begin Name := "Sanderson, Arthur"; Title := "Word processor"; end;
Примечание: Не забывайте о том, что наследуемые поля объектов не интерпретируются особым образом только потому, что они являются наследуемыми.
Именно сейчас вы должны запомнить (в конце концов это придет само собой), что наследуемые поля являются столь же доступными, как если бы они были объявлены внутри типа объекта. Например, даже если Name, Title и Rate не являются частью описания типа THourly (они наследованы от типа TEmployee), то вы можете ссылаться на них, словно они описаны в THourly:
AnHourly.Name := "Arthur Sanderson";
8 8 8
| |