Главная » Java » Расширенный класс Java

0

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

 

class Attr {

      private final String name;

      private Object value = null;

     

      public Attr(String name) {

            this.name = name;

      }

     

      publiс Attr(String name, Objeсt value) {

            this.name = name;

            this.value = value;

      }

       

      public String getName() {

            return name;

      }

      public Object getValue() {

            return value;

      }

     

      public Object setValue(Object newValue){

            Object oldVal = Value;

            Value = newValue;

            return oldValue;

      }

       

      public String toString() {

            return name + "=’" + value "’";

      }

}

 

Атрибут должен обладать именем, поэтому в каждом конструкторе класса Attr предусмотрен параметр name. Имя обязано оставаться неизменным (и с этой целью поле name помечено модификатором final), поскольку позже его, возможно, придется использовать в качестве ключа в структурах данных типа хеш-таблицы или отсортированного списка (если предположить, что в такой ситуации поле name допускает возможность модификации, значение атрибута окажется утраченным, поскольку оно хранится в таблице или списке под "старым" именем). Значения атрибутов могут относиться к любому типу, поэтому для их хранения предусмотрено поле типа Object . Значение позволено изменять без каких-либо ограничений и в любой момент. Как name, так и value объявлены посредством модификатора рrivate, так что доступ к ним осуществляется только с помощью соответствующих методов класса. В этом случае гарантируется выполнение контракта класса и обеспечивается свобода действий его автора детали реализации класса закрыты для доступа извне и могут быть изменены в будущем без ущерба для прикладных программ, использующих класс.

Каждый класс, который мы рассматривали до сих пор, строго говоря, можно было бы назвать производным (расширенным), независимо от того, был он объявлен таковым или нет. В объявлениях классов, подобных Attr, нет очевидного упоминания о каком-либо базовом классе, но все они косвенно наследуют класс Object . Object  – это корневой элемент иерархии классов Java. В составе класса Object объявлено несколько методов, которые реализуются во всех объектах (примером может служить метод toString, о котором мы говорили в главе 2). Переменная типа Object  способна хранить ссылку на любой объект – будь то экземпляр класса или массив. Более подробные сведения о классе Object  приведены в разделе 3.8 этой главы на странице 109.

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

 

class ColorAttr extends Attr {

       private Screencolor myColor; // Декодированный цвет

      

       public ColorAttr(String super(name, value){

                   super(name,value);

                   decodeColor();            

       }

        

}

public ColorAttr(String name) {

            this(name, "бесцветный");

}

public ColorAttr(String name, ScreenColor value) {

            super(name, value.toString());

            myColor = value;

}

public Object setVal(Object newValue) {

// сначала вызываем setvalue базового класса

            Object retval = super.setvalue(newValue);

            decodeColor();

            return retVal;   

}

/** присваивание в myColor объекта * screenColor, а не описания */

public screenColor setvalue(screencolor newValue) {

            // Вначале вызываем setvalue базового класса

            super. setValue(newValue.toString()) ;

ScreenColor oldValue = myColor;

myColor = newValue;

return oldValue;

}

/** получение объекта screenColor * с декодированным цветом */

public screenColor getColor() {

            return myColor;

}

/** присваивание в myColor значения,

* полученного из описания в value */

protected void decodeColor() {

            if (getValue() == null)

                  myColor = null;

            else

                  myColor = new screenColor(getValue());

}

}

 

 

 

 

Новый класс ColorAttr наследует (расширяет) класс Attr – он способен выполнять все функции класса Attr и наделен новыми. Таким образом, Attr это базовый класс, а СоlorАttr – производный. Иерархию классов – в направлении от производных к базовому – в данном случае можно изобразить следующим образом   Color -> Attr -> Object.

 

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

·      предлагает три версии конструкторов – два из них "зеркально" отображают функции конструкторов базового класса, а третий непосредственно взаимодействует с объектом screenColor;

·      единовременно переопределяет и перегружает метод setValue базового класса таким образом, чтобы обеспечить возможность задания новой цветовой составляющей атрибута;

·      содержит новый метод getColor, возвращающий значение, которое представляет собой описание цвета, преобразованное в объект ScreenColor.

В следующих разделах мы постараемся рассказать о тонкостях наследования и о ТОМ влиянии, которому в ходе этого процесса подвергаются различные члены класса.

Обратите внимание на использование в объявлении метода decodeColоr модификатора protected, который гарантирует, что метод будет доступен в текущем и производных классах, но закрыт для обращения извне. Подробное описание назначения модификатора protected приведено в разделе 3.5 этой главы на странице 1О2.

Упражнение 3.1. Взяв за основу объявление класса vehicle (вы должны были спроектировать его при выполнении упражнений главы 2), создайте расширенный класс passengervehi с’ е (легковой автомобиль), обеспечивающий средства учета общего количества пассажирских мест и числа тех, которые заняты в данный момент. Предложите для passengervehic, е версию метода main, позволяющего создать несколько экземпляров этого класса и вывести на экран их содержимое.

Источник: Арнолд, Кен, Гослинг, Джеймс, Холмс, Дэвид. Язык программирования Java. 3-е изд .. : Пер. с англ. – М. : Издательский дом «Вильяме», 2001. – 624 с. : ил. – Парал. тит. англ.

По теме:

  • Комментарии