Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ВВЕДЕНИЕ В ОБЪЕКТНО Ориентированное программиро...docx
Скачиваний:
19
Добавлен:
29.08.2019
Размер:
1.01 Mб
Скачать

Приведение объектных типов, операторы is и as

При организации иерархии наследования обычно методы, одинаковые для всех классов объявляют в классе-предке как статические, методы, одинаковые по назначению, но отличающиеся по реализации объявляют в классе-предке как виртуальные и динамические и перекрывают в потомках. Но есть поведение, уникальное для классов потомков не только по реализации, но и по назначению. Такие методы объявляют в классе-потомке. Если работать с объектом типа класс-потомок через указатель на класс-предок, то вызвать такие методы непосредственно нельзя, у класса-предка их просто нет. Для решения этой проблемы используется приведение объектных типов. Говоря другими словами, приведение объектных типов позволяет делать следующее: если указатель на объект имеет тип класс-предок а реальный объект принадлежит классу-потомку, имеющему новые методы, то добраться до этих методов можно только приведя тип указателя к тому классу, у которого эти методы уже есть. Для объектных типов, как и для любых других допустимо явное приведение типов:

TAnotherType(ASomeObject).Methodl

Проверки совместимости типов при этом не проводится. Поэтому использовать такой способ не рекомендуется. Для приведения объектных типов служит оператор as. С его помощью можно рассматривать экземпляр объекта как принадлежащий к другому совместимому типу:

(AsomeObject as TAnotherType).Methodl

Рассмотрим пример приведения объектных типов с использованием оператора as:

От стандартного способа приведения типов использование оператора as отличается наличием проверки на совместимость типов как во время компиляции, так и во время выполнения. Правило приведения типов - приводить объект можно либо к его реальному классу, либо к классу, который является предком его реального класса. При компиляции производится формальная проверка совместимости типов - если указатель на объект формально не может указывать на объект такого типа, то компилятор выдаст ошибку в этом операторе. Ошибки не будет, если мы пытаемся привести объект к типу класс, который является производным для типа указателя, так как вполне возможно, что реальный объект будет иметь именно этот тип или тип одного из его потомков. Но это не является гарантией правильности приведения - возможно мы пытаемся привести объект к классу, который не совпадает с его реальным классом и не является потомком его реального класса, хотя и его реальный класс и класс, к которому приводим являются потомками одного класса. В этом случае имеет место попытка приведения к несовместимому типу, которая приводит к возникновению исключительной ситуации (ИС).

После приведения сам объект остается неизменным, но вызываются те его методы, которые соответствуют присваиваемому классу.

Пример приведения объектных типов с проверкой совместимости и без нее:

Так как существуют ограничения на приведение объектных типов, иногда возникает необходимость проверять возможность приведения еще до его выполнения. Для этого может использоваться оператор is, проверяющий совместимость по присваиванию объекта с классом и возвращает true если типы совместимы, т.е. объект является экземпляром данного класса или одного из его потомков, и false в ином случае. Если оператор is при проверке совместимости объекта с классом возвращает true, то этот объект можно приводить к этому классу.

В одном из предыдущих примеров рассматривалась иерархия классов - геометрических фигур:

Добавим к этой иерархии объект рамка текста, помимо метода рисования рамки добавится метод вывода текста, которого не было в других классах:

Если работать с объектами этих классов как с массивом или передавать их в качестве параметров подпрограммы, доступ к методу Draw любого объекта не представляет труда. Но для доступа к методу TTextRectangle.OutText необходимо явно приводить типы. Оператор is используется, чтобы проанализировать, что данный объект реально является рамкой текста. В этом случае его тип приводится к типу класса рамка и вызывается его метод OutText. Например.

Очень полезными могут быть операторы is и as в методах - обработчиках событий. Для обеспечения совместимости обычно источник события Sender имеет тип ТObject, хотя реально им является форма или другие компоненты. Поэтому, чтобы иметь возможность пользоваться их методами и свойствами, применяются эти операторы вместе, либо только оператор as:

Приведение объектных типов приводит к изменениям в вызове только статически перекрытых методов. Виртуальные и динамические методы по-прежнему вызываются в соответствии с реальным типом объекта: