Материал предоставлен https://it.rfei.ru

Иерархия типов

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

Таблица 6.1. Типы и значения

Типы Значения
Примитивные типы данных значения примитивов
Класс, интерфейс, типы массивов (ссылочные типы) ссылочные значения

Массивы в Java являются объектами. Типы массивов (boolean[], Object[], StackImp[]) неявно образуют иерархию наследования. Иерархия наследования изображения на рис.6.3, может быть дополнена соответствующими типами массивов. Итоговая иерархия типов показана на рис. 6.4. Тип массива показан как «класс» с обозначением [], добавленным к имени типа элемента. Класс SafeStackImpl — это подкласс класса StackImpl. Соответствующие типы массивов, SafeStackImpl[] и StackImpl[], показаны как подтип и супертип соответственно в этой иерархии. На рис. 6.4 также показаны типы массивов, соответствующие некоторым примитивным типам данных SafsStackImpl

Рис.6.4 Иерархия ссылочного типа

Из иерархии типов на рис. 6.4 мы можем сделать следующие выводы.

  • Все ссылочные типы являются подтипами типа Object. Это применимо к классам, интерфейсам и типам массивов, так как они и есть все ссылочные типы.
  • Все массивы ссылочных типов являются также подтипами типа массива Object[], но массивы примитивных типов не являются таковыми. Обратите внимание, что тип массива Object[] является также подтипом типа Object.
  • Если ссылочный тип является подтипом другого ссылочного типа, то соответствующие типы массивов имеют аналогичное отношение подтип-супертип.
  • Не существует отношения подтип-супертип между типом и соответствующим ему типом массива.

Можно создать массив интерфейсного типа, но от интерфейса нельзя породить объект (как случае с абстрактными классами). В операторе объявления ниже ссылка iSafeStackArray имеет тип ISafeStack[] (т.е. массив интерфейсного типа ISafeStack). Выражение создания массива создает массив, чьи элементы относятся к типу ISafeStack. Объект массива может содержать пять ссылок типа ISafeStack. В следующем объявлении эти ссылки не инициализируются.

ISafeStack[] iSafeStackArray = new ISafeStack[5];

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

Следующее присваивание допустимо, так как ссылка супертипа (StackStackImp[]) может указывать на объекты его подтипа (SafeStacklmpl[]).

StackImpl[] stackImplArray = new SafeStackImpl[2]; // (1)

Поскольку StackImpl является супертипом SafeStackImpl, следующее присваивание тоже допустимо.

stackImplArray[0] = new SafeStackImpl(10);         // (2)

Присваивание в строке (2) добавляет объект SafeStackImpl в объект SafeStackImpl[] (т.е. массив SafeStackImpl), созданный в (1).

Так как тип массива stackImplArray[i], (0 < i < 2), — это тип StackImpl, то должно быть возможно следующее присваивание.

stackImplArray[1] = new StackImpl(20);             // (3) Выбросит исключение

На этапе компиляции никаких проблем не возникнет, так как компилятор не может проследить, что переменная массива stackImplArray реально обозначает во время выполнения объект SafeStackImpl[].

Однако присваивание в строке (3) вызывает исключение ArrayStoreException, которое будет выброшено на этапе выполнения, так как объект SafeStackImpl[] может содержать объекты типа StackImpl.

ИнтерфейсыПреобразование типов значений ссылок