русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Преобразование ссылочных типов (расширение и сужение)


Дата добавления: 2015-06-12; просмотров: 1326; Нарушение авторских прав


Переходим к ссылочным типам. Преобразование объектных типов всего иллюстрируется с помощью дерева наследования. Рассмотрим большой пример наследования:

// Объявляем класс Parent class Parent {intx; }

// Объявляем класс Child и наследуем // его от класса Parent class Child extends Parent {inty; }

// Объявляем второго наследника // класса Parent - класс Child2 class Child2 extends Parent {intz;}

В каждом классе объявлено поле с уникальным именем. Будем рас­сматривать это поле, как пример набора уникальных свойств, присущих некоторому объектному типу.

Три объявленных класса могут порождать три вида объектов. Объ­екты класса Parent обладают только одним полем х, а значит, только ссылки типа Parent могут ссылаться на такие объекты. Объекты класса Child обладают полем у и полем х, полученным по наследству от класса Parent. Стало быть, на такие объекты могут указывать ссылки типа Child или Parent. Второй случай уже иллюстрировался следующим примером:

Parent р = new Child();

Обратите внимание, что с помощью такой ссылки р можно обра­щаться лишь к полю X созданного объекта. Поле у недоступно, так как компилятор, проверяя корректность выражения р.у, не может предуга­дать, что ссылка р будет указывать на объект типа Child во время испол­нения программы. Он анализирует лишь тип самой переменной, а она объявлена как Parent, но в этом классе нет поля у, что и вызовет ошибку компиляции.

Аналогично, объекты класса Child2 обладают полем z и полем х, по­лученным по наследству от класса Parent. Значит, на такие объекты могут указывать ссылки типа Child2 или Parent.

Таким образом, ссылки типа Parent могут указывать на объект любо­го из трех рассматриваемых типов, а ссылки типа Child и Child2 – только а объекты точно такого же типа. Теперь можно перейти к преобразованию ссылочных типов на основе такого дерева наследования.



Расширение означает переход от более конкретного типа к менее конкретному, т.е. переход от детей к родителям. В нашем примере преоб­разование от любого наследника (Child, Child2) к родителю (Parent) есть расширение, переход к более общему типу. Подобно случаю с примитивными типами, этот переход производится самой JVM при необходимости и незаметен для разработчика, то есть не требует никаких дополнительных усилий, так как он всегда проходит успешно: всегда можно обращаться к объекту, порожденному от наследника, по типу его родителя.

Parent p1=new Child О; Parent p2=new Child2();

В обеих строках переменным типа Parent присваивается значение другого типа, а значит, происходит преобразование. Поскольку это рас­ширение, оно производится автоматически и всегда успешно.

Обратите внимание, что при подобном преобразовании с самим объектом ничего не происходит. Несмотря на то, что, например, поле у класса Child теперь недоступно, это не означает, что оно исчезло. Такое существенное изменение структуры объекта невозможно. Он был порож­ден от класса Child и сохраняет все его свойства. Изменился лишь тип ссылки, через которую идет обращение к объекту. Эту ситуацию можно условно сравнить с рассматриванием некоего предмета через подзорную трубу если перейти от трубы с большим увеличением к более слабой, то видимых деталей станет меньше, но сам предмет, конечно, никак от это­го не изменится.

Следующие преобразования являются расширяющими:

• от класса А к классу В, если А наследуется от В (важным частным случаем является преобразование от любого ссылочного типа к Object);

• от null-типа к любому объектному типу

Второй случай иллюстрируется следующим примером:

Parent p=null;

Пустая ссылка null не обладает каким-либо конкретным ссылочным узлом, поэтому иногда говорят о специальном null-типе. Однако на практике важно, что такое значение можно прозрачно преобразовать к любому векторному типу

С Изучением остальных ссылочных типов (интерфейсов и массивов)

список будет расширяться.

Обратный переход, то есть движение по дереву наследования вниз, наследникам, является сужением. Например, для рассматриваемого случая, переход от ссылки типа Parent, которая может ссылаться на объекты трех классов, к ссылке типа Child, которая может ссылаться на объекты лишь одного из трех классов, очевидно, является сужением. Такой переход может оказаться невозможным. Если ссылка типа Parent ссылается на объект типа Parent или Child2, то переход к Child невозможен, ведь в обоих случаях объект не обладает полем у, которое объявлено в классеChild. Поэтому при сужении разработчику необходимо явным образом указывать на то, что необходимо попытаться провести такое преобразование. JVM во время исполнения проверит корректность перехода. Если он возможен, преобразование будет проведено. Если же нет - возникнет ошибка.

Parent p=newChild();

Child c=(Child)p; // преобразование будет успешным.

Parent p2=new Child2();

Child c2=(Child)p2; // во время исполнения возникнет ошибка!

Чтобы проверить, возможен ли желаемый переход, можно восполь­зоваться оператором instanceof: Parent p=new Child(); if (p instanceof Child) { Child с = (Child)p;}

Parent p2=newChild2(); if (p2 instanceof Child) { Child с = (Child)p2;}

Parent p3=new Parent();

if (p3 instanceof Child) {Childc = (Child)p3; }

В данном примере ошибок не возникнет. Первое преобразование возможно, и оно будет осуществлено. Во втором и третьем случаях условия операторов if не сработают и попыток некорректного перехода не будет.

На данный момент можно назвать лишь одно сужающее преобразование:

• от класса А к классу В, если В наследуется от А (важным частным случаем является сужение типа Object до любого другого ссылочного типа)-

С изучением остальных ссылочных типов (интерфейсов и массивов) этот список будет расширяться.



<== предыдущая лекция | следующая лекция ==>
Long: -9223372036854775808. .9223372036854775807 | Применение приведений


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 3.852 сек.