Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых
[Назад]

Библиотека примеров приложений Java

Оглавление
Базовые типы

Замещающие типы
Без указателей
Массивы
Структурное программи-
рование

Обработка исключений
Возбуждение исключений
Классы обработки исключений
Блок finally
Строки String
Класс Math
Класс Vector
Класс Stack
Словарь на базе Hashtable
Словарь на базе Properties
Цифровые часы
Собственный класс
Наследование классов

Интерфейсы

Назад

1.19. Применение интерфейсов

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

Исходный текст примера

Архив проекта для Java WorkShop 2.0

Демонстрация
(ваш браузер должен уметь работать с аплетами Java)

Немного теории

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

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

Если в определении класса указано, что он реализует тот или иной интерфейс, то чтобы такой класс не стал абстрактным, в нем должны находится определения всех методов, перечисленных в интерфейсе.

Абстрактный класс, в котором определены не все методы реализуемого им интерфейса, нельзя применять для создания объектов. Тем не менее, на его основе можно образовывать дочерние классы. Чтобы такой дочерний класс не стал абстрактным, в нем следует определить методы интерфейса, не определенные в базовом классе.

Описание примера

Аплет ColorInterface рисует в своем окне закрашенные прямоугольники произвольного размера и цвета (рис. 1).

pic01.gif (7487 bytes)

Рис. 1. Окно аплета ColorInterface

Цветные прямоугольники являются объектами класса MyColorRect, созданного на базе класса MyRect, инкапсулирующем поведение бесцветных прямоугольников.

Изучение исходного текста аплета мы начнем с класса MyRect. Этот класс реализует сразу два интерфейса с именами DrawMyRectangles и RandomValue:

class MyRect 
  implements DrawMyRectangles, RandomValue
{
  protected int x;
  protected int y;
  protected int width;
  protected int height;
  
  MyRect()
  {
    x = y = width = height = 0;
  }
  
  public void setRandomSize(
    Dimension dimAppWndDimension)
  {
      x = getRandomValue(
        dimAppWndDimension.width);
      y = getRandomValue(
        dimAppWndDimension.height);
      
      width  = getRandomValue(
        dimAppWndDimension.width) / 2;
      height = getRandomValue(
        dimAppWndDimension.height) / 2;
  }
  
  public void drawMyRect(Graphics g)
  {
    g.fillRect(x, y, width, height);
  }
  
  public int getRandomValue(int maxValue)
  {
    return (int)(maxValue * Math.random());
  }
}

Защищенные поля x, y, width и height хранят, соответственно, координаты (x, y) левого верхнего угла прямоугольника, ширину и высоту.

Конструктор класса MyRect инициализирует эти поля при создании нового объекта, записывая туда нулевые значения.

Метод setRandomSize устанавливает случайные размеры и расположение прямоугольника, вызывая для этого метод getRandomValue. Максимальные значения для случайных величин передаются этому методу через единственный параметр.

Метод drawMyRect рисует прямоугольник в контексте отображения g, пользуясь методом fillRect.

И, наконец, метод getRandomValue получает значение случайного числа при помощи метода random из класса Math.

Обратимся теперь к интерфейсам, которые реализует рассмотренный нами класс MyRect. Их определение приведено ниже:

interface DrawMyRectangles
{
  void drawMyRect(Graphics g);
}

interface RandomValue
{
  int getRandomValue(int maxValue);
}

В интерфейсе DrawMyRectangles находится прототип метода drawMyRect, а в интерфейсе RandomValue - прототип метода getRandomValue.

Так как класс MyRect реализует оба этих интерфейса, чтобы не стать абстрактным, он должен содержать определение обоих методов. Так и есть на самом деле.

Однако класс MyRect не имеет дела с цветными прямоугольниками, так как в нем нет никаких полей или методов, предназначенных для работы с цветом. Поведение цветных прямоугольников мы описали в классе MyColorRect, созданном на базе класса MyRect. Дополнительно этот класс реализует интерфейс DrawMyRectangles:

class MyColorRect 
  extends MyRect 
  implements DrawMyRectangles
{
  protected Color rectColor;
  
  MyColorRect()
  {
    super();
    rectColor = Color.black;
  }
  
  public void setRandomColor()
  {
    int rColor, gColor, bColor;
    
    rColor = getRandomValue(255);
    gColor = getRandomValue(255);
    bColor = getRandomValue(255);
    
    rectColor = new Color(
      rColor, gColor, bColor);
  }
  
  public void drawMyRect(Graphics g)
  {
    g.setColor(rectColor); 
    g.fillRect(x, y, width, height);
  }
}

В защищенном поле rectColor хранится цвет прямоугольника. При создании объекта класса MyColorRect конструктор устанавливает в этом поле черный цвет. Перед установкой цвета вызывается конструктор базового класса MyRect, устанавливающий координаты и размеры прямоугольника, равные нулю.

Для установки случайного цвета прямоугольника мы применили метод setRandomColor. Он три раза обращается к методу getRandomValue, получая случайные значения для отдельных компонент цвета.

Обратите внимание, что метод getRandomValue определен в дочернем классе MyRect. Поэтому методы класса MyColorRect, созданного на базе MyRect, могут обращаться к нему непосредственно.

Так как класс MyColorRect реализует интерфейс DrawMyRectangles, в нем мы определили метод drawMyRect. Прототип этого метода определен в данном интерфейсе. Чтобы нарисовать цветной прямоугольник, этот метод устанавливает цвет в контексте отображения, передаваемый через параметр g.

Как происходит рисование прямоугольников?

Наш аплет является многопоточным. При активизации он создает объект класса DrawRect, унаследованного от класса Thread. Метод run этого класса работает как отдельный поток одновременно с главным потоком аплета:

public void run()
{
  MyColorRect rc = new MyColorRect();
    
  while (true)
  {
    rc.setRandomSize(dimAppWndDimension);
    rc.setRandomColor();
    rc.drawMyRect(g);
      
    try
    {
      Thread.sleep(50);
    }
    catch (InterruptedException e)
    {
      stop();
    }
  }
}

Как видно из приведенного выше исходного текста, после создания объекта класса MyColorRect (являющегося цветным прямоугольником), метод run в бесконечном цикле с задержкой изменяет его расположение, размеры и цвет, а затем отображает в окне аплета.

Установка случайного расположения и размеров выполняется методом setRandomSize, определенным в базовом классе бесцветных прямоугольников MyRect. Для изменения цвета мы пользуемся методом setRandomColor, определенном в классе цветных прямоугольников MyColorRect.

Метод drawMyRect определен и в классе MyRect, и в классе MyColorRect. Так как в данном случае он вызывается для объекта rc класа MyColorRect, то работает "цветная" реализация этого метода из класса MyColorRect.

Назад

[Назад]