Главная страница Случайная страница Разделы сайта АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Отношения между классами
Если предположить, что классы и объекты в ООП являются отражением понятий реальной жизни, то легко можно установить те отношения, которые могут существовать между классами. Первый тип отношений соответствует ситуации, когда один класс включает в себя объекты других классов. Такой тип отношений называется агрегированием (иначе называемым отношением has-a или отношением part-of). Данный тип отношения моделируется включением в класс полей-объектов. Например, класс для представления группы людей может иметь следующее описание: type TCrowd = class fPeople: array[1..100] of TPerson; ... end; Для классов, реализующих агрегирование, конструктор, как правило, занимается созданием объектов-полей, а деструктор уничтожает эти объекты: constructor TCrowd.Create; var i: Integer; begin for i: = 1 to 100 do fPeople[i]: = TPerson.Create end; Следующий тип отношений связан с ситуацией, когда понятие, соответствующее одному классу, уточняется понятием, соответствующим другому классу. Пусть необходим класс для описания служащих – TEmployee. Можно рассуждать так: любой служащий является человеком (TPerson), но служащий – это такой человек, который получает зарплату. Отношение между классами TEmployee и TPerson называется наследованием (отношение is-a). Наследование является одним из базовых принципов ООП. Наследование предполагает создание новых классов на основе существующих. В нашем случае мы можем не писать класс TEmployee «с нуля», а воспользоваться классом TPerson как основой. При наследовании новый класс называется классом-потомком (или дочерним классом, производным классом), старый – классом-предком (или родительским классом, базовым классом). При помощи наследования можно строить так называемое дерево классов (или иерархию классов), последовательно уточняя описание класса и переходя от общих понятий к частным. Рассмотрим синтаксис наследования классов. В Object Pascal при объявлении класса-потомка имя класса-предка указывается после ключевого слова class в круглых скобках. Описание класса-потомка включает только те элементы, которых нет в предке, так как потомок получает все элементы предка автоматически. Описание класса TEmployee может выглядеть следующим образом: type TEmployee = class(TPerson) private fSalary: double; procedure SetSalary(Value: double); public property Salary: double read fSalary write SetSalary; end; Как наследник, TEmployee содержит все поля, методы и свойства TPerson и, кроме этого, добавляет собственное поле fSalary, метод SetSalary и свойство Salary. Объекты классов-потомков совместимы по присваиванию с объектами классов-предков. При этом действует следующее правило: объекту родительского класса можно присвоить объект дочернего класса, но не наоборот: var Man: TPerson; Employee: TEmployee; Employee: TEmployee; ... Man: = Employee; // допустимо Employee: = Man; // ошибка компиляции Обосновывается вышеуказанное правило следующим образом. Так как дочерний класс может добавлять к родительскому классу новые поля, то при присваивании объекту дочернего класса объекта родительского класса обращение к новым полям приведёт к выходу за границу памяти объекта родительского класса. Это является недопустимым. Отметим следующие особенности объектной модели Object Pascal. Наследование в Object Pascal разрешено только от одного предка. Все классы в Object Pascal имеют одного общего предка. Таким предком является класс TObject. Объявления TPerson = class и TPerson = class(TObject) полностью эквивалентны. Класс TObject содержит пустой конструктор Create и пустой деструктор Destroy, которые можно применять в простых классах (этот факт использовался в некоторых примерах). С наследованием связана директива ограничения видимости protected. Элементы класса из секции protected могут использоваться вне пределов модуля с объявлением класса, но только потомками класса.
|