Учим Java. Объектно-ориентированное программирование и основные синтаксические конструкции. (часть 3)

Учим Java. Объектно-ориентированное программирование
и основные синтаксические конструкции. (часть 3)
В этой статье мы познакомимся с базовым понятием класса в Java, а также рассмотрим приемы объектно-ориентированного программирования. Это, собственно, одна из самых важных тем при изучении любого объектно-ориентированного языка. Тем более такого, как Java. Начнем, пожалуй.

Как уже было сказано выше, класс — это базовый элемент объектно-ориентированного программирования в языке Java. Основная идея класса заложена в самом названии. Класс — это шаблон для создания объектов, экземпляров класса. Класс объединяет в себе методы и поля, которые описывают поведение объекта этого класса. Классический пример, который наглядно показывает, что собой представляет объектно-ориентированное программирование, — это описание какой-нибудь фигуры, например окружности. Для того чтобы описать класс объектов, описывающий окружность, объявим класс Circle. Это будет выглядеть следующим образом:
class Circle
{
}
Пока наш класс не имеет ни одного поля и ни одного метода. Думаю, вам знакомы такие понятия из геометрии, как центр окружности и ее радиус. Именно этими параметрами и определяется окружность. Теперь добавим поля для координат центра окружности и радиуса в наш класс:
class Circle
{
int x, y, Radius;
}
Теперь объекты (экземпляры) этого класса могут иметь свои собственные значения этих полей. Еще в самой первой статье я приводил пример программы на Java, для того чтобы вы могли проверить работоспособность своего JDK. Я там уже упоминал о том, что любая программа на Java — это класс, который имеет метод main(). Причем имя этого класса должно полностью совпадать с именем файла. Так вот, создадим основной класс программы MyApp1 и сохраним его в файле MyApp1.java:
class MyApp1
{
public static void main(String argv[])
{
}
}
Теперь добавим описанный нами класс Circle к этой программе и сразу создадим несколько объектов этого класса в методе main() класса MyApp1:
class MyApp1
{
public static void main(String argv[])
{
Circle c1,c2;
с1 = new Circle();
c2 = new Circle();
c1.x = 100; c1.y = 90; c1.Radius = 20;
c2.x = 200; c2.y = 100; c2.Radius = 20;
}
}

class Circle
{
int x, y, Radius;
}
Из этого примера мы имеем фактически две разные окружности. У каждой из них есть свой радиус и свои координаты центра. Для того чтобы определить какие-нибудь действия над экземплярами класса Circle, в нем нужно определить соответствующие методы. Например, метод show() (показать) и hide() (спрятать) окружность. При выполнении своей работы эти методы будут пользоваться свойствами класса Circle, т.е. координатами центра и радиусом. В этих методах описываем соответственно прорисовку окружности и ее сокрытие. Не будем останавливаться на реализации этих методов. Главное необходимо усвоить, что любой метод соответствующего класса может пользоваться уже существующими свойствами этого класса как заранее определенными переменными.
public void show()
{
// рисуем окружность
}

public void hide()
{
// убираем окружность
}
Как дополнение можно определить еще несколько методов.
Предположим, нам захотелось реализовать объект часы (Clock), которые будут состоять из окружности и одной секундной стрелки, движущейся по этой окружности. В этом случае как нельзя кстати нам подойдет уже описанный класс Circle. Для того чтобы использовать его со всеми его свойствами и методами в нашем новом классе Clock, воспользуемся таким понятием объектно-ориентированного программирования, как наследование. Создадим класс-потомок Clock, который унаследует методы и свойства класса Circle:
class Clock extends Circle
{
}
Теперь у класса Clock есть все те свойства, которые были в классе Circle. Это координаты центра и радиус. Для того чтобы реализовать в полной мере класс Clock, нам необходимо объявить еще одно поле. Это поле будет хранить текущую позицию секундной стрелки. Так как секунд у нас будет 60 при полном обороте, то для этого свойства будет достаточно разрядности типа byte.
class Clock extends Circle
{
byte sPos;
}
После этого к классу Clock добавим методы start() и stop(), которые будут запускать и останавливать часы. Прорисовка часов реализуется в соответствии со значениями полей x, y, Radius и sPos.
public void start()
{
// запустить часы, начиная со значения sPos
}

public void stop()
{
// остановить часы, при этом не обнуляя значение свойства sPos
}
Опять же реализация этих методов пока не столь важна для нас. Главное понять суть основных концепций объектно-ориентированного программирования.
На примере класса Clock познакомимся более подробно с понятием конструктора в Java. Конструктор — это тот же метод класса, имя которого совпадает с именем класса, используется для инициализации свойств класса и при выполнении необходимых действий при создании экземпляра класса. В нашем случае важно при создании экземпляра объекта Clock, задать начальные значения всем свойствам этого класса, в том числе и начальной позиции секундной стрелки часов sPos. Для создания конструктора определим метод класса Clock с таким же именем:
Clock(int px, int py, int pRadius, int psPos)
{
x = px;
y = py;
Radius = pRadius;
sPos = psPos
}
Очень важно, что конструктор ничего не должен возвращать, даже void. Итак, наш класс в общем виде будет выглядеть следующим образом:
class Clock extends Circle
{
int sPos;

Clock(int px, int py, int pRadius, int psPos)
{
x = px;
y = py;
Radius = pRadius;
sPos = psPos
}

public void start()
{
// запустить часы, начиная со значения sPos
}

public void stop()
{
// остановить часы, при этом не обнуляя значение свойства sPos
}

}
В итоге имеет два класса: Circle и Clock. Методы и свойства класса Circle наследуются классом Clock. Приведем пример использования класса Clock в методе main() какого-нибудь из классов вашей основной программы:
public static void main(String argv[])
{
Clock cl;
cl = new Clock(150, 150, 50, 0);
cl.start(); // часы пошли. Этот метод лучше реализовать в отдельном треде (потоке), чтобы после можно было
// из любого места основной программы их остановить. Потоки мы рассмотрим более подробно
// позже
}
Касательно конструкторов осталось упомянуть, что такого понятия, как деконструктор (C++), в Java нет. Все дело в том, что в Java все же был реализован собственный сборщик мусора. Это означает, что вам не надо беспокоиться об удалении из памяти своих объектов, сборщик мусора сделает это за вас. Однако не стоит понимать факт отсутствия такого сборщика в C++ как недостаток последнего. Просто в то время реализацию сборщика для языка, ориентированного на системное программирование, посчитали не обоснованным и не нужным. Другое дело — Java.
На этом можно закончить общее ознакомление с некоторыми основами объектно-ориентированного программирования в Java. С вопросами и предложениями — пишите.

Алексей Литвинюк, Litvinuke@tut.by



Компьютерная газета. Статья была опубликована в номере 10 за 2002 год в рубрике программирование :: java

©1997-2024 Компьютерная газета