Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
GoslingJava2.doc
Скачиваний:
139
Добавлен:
23.02.2016
Размер:
2.39 Mб
Скачать

1.10.1.Класс Object

Классы, для которых не указан расширяемый класс, являются неявным расширением класса Object. Все ссылки на объекты полиморфно относятся к классу Object, который является базовым классом для всех ссылок, которые могут относиться к объектам любого класса:

Object oref = new Pixel();

oref = “Some String”;

В этом примере объекту oref вполне законно присваиваются ссылки на объекты Pixel и String, невзирая на то что эти классы не имеют между собой ничего общего— за исключением неявного суперкласса Object.

В классе Object также определяется несколько важных методов, рассмотренных в главе 3.

1.10.2.Вызов методов суперкласса

Чтобы очистка объектов класса Pixel происходила правильно, мы заново реализовали метод clear. Его работа начинается с того, что с помощью ссылки super вызывается метод clear суперкласса. Ссылка super во многих отношениях напоминает уже упоминавшуюся ранее ссылку this, за тем исключением, что super используется для ссылок на члены суперкласса, тогда как this ссылается на члены текущего объекта.

Вызов super.clear() обращается к суперклассу для выполнения метода clear точно так же, как он обращался бы к любому объекту суперкласса— в нашем случае, класса Point. После вызова super.clear() следует новый код, который должен присваивать color некоторое разумное начальное значение. Мы выбрали null— то есть отсутствие ссылки на какой-либо объект.

Что бы случилось, если бы мы не вызвали super.clear()? Метод clear класса Pixel присвоил бы полю цвета значение null, но переменные x и y, унаследованные от класса Point, остались бы без изменений. Вероятно, подобная частичная очистка объекта Pixel, при которой упускаются унаследованные от Point поля, явилась бы ошибкой в программе.

При вызове метода super.method() runtime-система просматривает иерархию классов до первого суперкласса, содержащего method(). Например, если бы метод clear отсутствовал в классе Point, то runtime-система попыталась бы найти такой метод в его суперклассе и (в случае успеха) вызвала бы его.

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

Point point = new Pixel();

point.clear(); // используется метод clear() класса Pixel

В этом примере будет вызван метод clear класса Pixel, несмотря на то что переменная, содержащая объект класса Pixel, объявлена как ссылка на Point.

1.11. Интерфейсы

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

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

interface Lookup {

/** Вернуть значение, ассоциированное с именем, или

null, если такого значения не окажется */

Object find(String name);

}

В интерфейсе Lookup объявляется всего один метод find, который получает значение (имя) типа String и возвращает значение, ассоциированное с данным именем, или null, если такого значения не найдется. Для объявленного метода не предоставляется никакой конкретной реализации— она полностью возлагается на класс, в котором реализуется данный интерфейс. Во фрагменте программы, где используются ссылки на объекты Lookup (объекты, реализующие интерфейс Lookup), можно вызвать метод find и получить ожидаемый результат независимо от конкретного типа объекта:

void processValues(String[] names, Lookup table) {

for (int i = 0; i < names.length; i++) {

Object value = table.find(names[i]);

if (value != null)

processValue(names[i], value);

}

}

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

class SimpleLookup implements Lookup {

private String[] Names;

private Object[] Values;

public Object find(String name) {

for (int i = 0; i < Names.length; i++) {

if (Names[i].equals(name))

return Values[i];

}

return null;

}

// . . .

}

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

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

Упражнение 1.13

Напишите расширенный интерфейс Lookup с добавлением методов add и remove. Реализуйте его в новом классе.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]