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

3.1. Расширенный класс

Каждый класс из тех, что встречались нам в этой книге, является расширенным, независимо от того, объявлен ли он с ключевым словом extends или нет. Даже такие классы, как Body, которые вроде бы не расширяют других классов, на самом деле неявно происходят от принадлежащего Java класса Object. Другими словами, Object находится в корне всей иерархии классов. В нем объявляются методы, которые реализованы во всех объектах. Переменные типа Object могут ссылаться на любые объекты, будь это экземпляры класса или массивы.

Например, при разработке класса для списка, элементы которого могут быть объектами произвольного типа, можно предусмотреть в нем поле типа Object. В такой список не могут входить значения примитивных типов (int, boolean и т.д.), однако при необходимости можно создать объекты этих типов спомощью классов-оболочек (Integer, Boolean и т.д.), описанных в главе 13.

Для демонстрации работы с подклассами начнем с базового класса для хранения атрибутов, представленных в виде пар имя/значение. Имена атрибутов являются строками (например, “цвет” или “расположение”). Атрибуты могут иметь произвольный тип, поэтому их значения хранятся в переменных типа Object:

class Attr {

private String name;

private Object value = null;

public Attr(String nameOf) {

name = nameOf;

}

public Attr(String nameOf, Object valueOf) {

name = nameOf;

value = valueOf;

}

public String nameOf() {

return name;

}

public Object valueOf() {

return value;

}

public Object valueOf(Object newValue) {

Object oldVal = value;

value = newValue;

return oldVal;

}

}

Каждому атрибуту обязательно должно быть присвоено имя, поэтому при вызове конструкторов Attr им передается параметр-строка. Имя должно быть доступно только для чтения, поскольку оно может применяться, скажем, в качестве ключа хеш-таблицы или сортированного списка. Если при этом имя атрибута будет изменено за пределами класса, то объект-атрибут “потеряется”, так как в таблице или списке он будет храниться под старым именем. Значение атрибута можно менять в любой момент.

Следующий класс расширяет понятие атрибута для хранения цветовых атрибутов, которые могут быть строками, служащими для именования или описания цветов. Описания цветов могут представлять собой как названия (“красный” или “бежевый”), по которым необходимо найти нужное значение в таблице, так и числовые значения, которые могут преобразовываться в стандартное, более эффективное представление ScreenColor (которое, как предполагается, определено в другом месте программы). Преобразование описания в объект ScreenColor сопряжено с большими накладными расходами, так что для каждого атрибута эту операцию желательно выполнять только один раз. Для этого мы расширяем класс Attr и создаем на его основе класс ColorAttr, включающий специальный метод для получения преобразованного объекта ScreenColor. Данный метод реализован так, что преобразование выполняется всего один раз:

class ColorAttr extends Attr {

private ScreenColor myColor; // преобразованный цвет

public ColorAttr(String name, Object value) {

super(name, value);

decodeColor();

}

public ColorAttr(String name) {

this(name, “transparent”);

}

public ColorAttr(String name, ScreenColor value) {

super(name, value.toString());

myColor = value;

}

public Object valueOf(Object newValue) {

// сначала выполнить метод valueOf() суперкласса

Object retval = super.valueOf(newValue);

decodeColor();

return retval;

}

/** Присвоить атрибуту ScreenColor значение,

а не описание */

public ScreenColor valueOf(ScreenColor newValue) {

// сначала выполнить метод valueOf() суперкласса

super.valueOf(newValue.toString());

myColor = newValue;

return newValue;

}

/** Вернуть преобразованный объект ScreenColor */

public ScreenColor color() {

return myColor;

}

/** Задать ScreenColor по описанию в valueOf */

protected void decodeColor() {

if (valueOf() == null)

myColor = null;

else

myColor = new ScreenColor(valueOf());

}

}

Сначала мы создаем новый класс ColorAttr, расширяющий класс Attr. Основные функции класса ColorAttr те же, что и у класса Attr, но к ним добавляется несколько новых. Класс Attr является суперклассом по отношению к ColorAttr, а ColorAttr— подклассом по отношению к Attr. Иерархия классов для нашего примера выглядит следующим образом (суперкласс на диаграмме расположен выше своего подкласса):

Расширенный класс ColorAttr выполняет три основные функции:

  • Он обеспечивает наличие трех конструкторов: два из них копируют поведение суперкласса, а третий позволяет сразу передать объект Screen Color.

  • Он перегружает и переопределяет метод valueOf базового класса, чтобы при изменении значения атрибута создался объект ScreenColor.

  • Он включает новый метод color для возврата цветового описания, преобразованного в объект ScreenColor.

Упражнение 3.1

На основе класса Vehicle из главы2 создайте расширенный класс с именем PassengerVehicle и наделите его возможностью определения числа свободных и занятых мест в машине. Включите в PassengerVehicle новый метод main, который создает несколько объектов и выводит их.

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