Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по основам ООП.docx
Скачиваний:
1
Добавлен:
01.04.2025
Размер:
5.29 Mб
Скачать

Экземпляры

С введением полиморфизма нам требуется уточнить терминологию, связанную с экземплярами. Содержательно, экземпляры класса - это объекты времени выполнения, построенные в соответствии с определением класса. Но сейчас в этом качестве нужно также рассматривать объекты, построенные для собственных потомков класса. Вот более точное определение:

Определение: прямой экземпляр, экземпляр

Прямой экземпляр класса C - это объект, созданный в соответствии с точным определением C с помощью команды создания create x ... , в которой цель x имеет тип C (или, рекурсивно, путем клонирования прямого экземпляра C ).

Экземпляр C - это прямой экземпляр потомка C .

Из последней части этого определения следует, что прямой экземпляр класса C является также экземпляром C , так как класс входит во множество своих потомков.

Таким образом, выполнение фрагмента:

p1, p2: POLYGON; r: RECTANGLE

...

create p1 ...; create r ...; p2 := r

создаст два экземпляра класса POLYGON , но лишь один прямой экземпляр (тот, который присоединен к p1 ). Другой объект, на который указывают p2 и r , является прямым экземпляром класса RECTANGLE , а следовательно, экземпляром обоих классов POLYGON и RECTANGLE .

Хотя понятия прямого экземпляра и экземпляра определены выше для классов, они естественно распространяются на любые типы (с базовым классом и возможными родовыми параметрами).

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

Статико-динамическая согласованность типов

Сущность типа T может во время исполнения прикрепляться только к экземплярам класса T .

Статический тип, динамический тип

Название последнего свойства предполагает различение "статического типа" и "динамического типа". Тип, который используется при объявлении некоторого элемента, является статическим типом соответствующей ссылки. Если во время выполнения эта ссылка присоединяется к объекту некоторого типа, то этот тип становится динамическим типом этой ссылки.

Таким образом, при объявлении p: POLYGON статический тип ссылки, обозначенной p , есть POLYGON , после выполнения create p динамическим типом этой ссылки также является POLYGON , а после присваивания p := r , где r имеет тип RECTANGLE и не пусто, динамическим типом становится RECTANGLE .

Правило согласования типов утверждает, что динамический тип всегда должен соответствовать статическому типу.

Чтобы избежать путаницы напомним, что мы имеем дело с тремя уровнями: сущность - это некоторый идентификатор в тексте класса, во время выполнения ее значение является ссылкой (за исключением развернутого случая), ссылка может быть присоединена к объекту .

У объекта имеется только динамический тип, который он получил в момент создания. Этот тип во время жизни объекта не изменяется.

В каждый момент во время выполнения у ссылки имеется динамический тип, тип того объекта, к которому она сейчас присоединена (или специальный тип NONE , если эта ссылка пуста). Динамический тип может изменяться в результате операций переприсоединения.

Только у сущности имеются и статический, и динамический типы. Ее статический тип - это тип, с которым она была объявлена: если объявление имеет вид x: T , то этим типом будет T . Ее динамический тип в каждый момент выполнения - это тип значения этой ссылки, т.е. того объекта, к которому она присоединена.

В развернутом случае нет ссылки, значением x является объект типа T , и T является и статическим типом и единственно возможным динамическим типом для x .