Главная » Java » Методы и параметры

0

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

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

Каждый метод имеет ноль или более параметров. Метод может возвращать значение или объявляться с ключевым словом void, которое означает, что метод ничего не возвращает. Операторы метода содержатся в блоке между фигурными скобками { и }, которые следуют за именем метода и объявлением его сигнатуры. Сигнатурой называется имя

метода, сопровождаемое числом и типом его параметров. Можно усовершенствовать  класс

Point и добавить в него простой метод clear, который выглядит так:

public void clear() {

x = 0;

y = 0;

}

Метод clear не имеет параметров, поскольку в скобках ( и ) после его имени ничего нет; кроме того, этот метод объявляется с ключевым словом void, поскольку он не возвращает никакого значения. Внутри метода разрешается прямое именование полей и методов класса — можно просто написать x и y, без ссылки на конкретный объект.

1.7.1. Вызов метода

Объекты обычно не работают непосредственно с данными других объектов, хотя, как мы видели на примере класса Point, класс может сделать свои поля общедоступными. И все же в хорошо спроектированном  классе данные обычно скрываются, чтобы они могли изменяться только методами этого класса. Чтобы вызвать метод, необходимо указать имя объекта и имя метода и разделить их точкой (.). Параметры передаются методу в виде заключенного в скобки списка значений, разделяемых запятыми. Даже если метод вызывается без параметров, все равно необходимо указать пустые скобки. Объект, для

которого вызывается метод (объект, получающий запрос на вызов метода) носит название

объекта-получателя, или просто получателя.

В качестве результата работы метода может возвращаться только одно значение. Чтобы метод возвращал несколько значений, следует создать специальный объект, единственное назначение которого — хранение возвращаемых значений, и вернуть этот объект.

Ниже приводится метод с именем distance, который входит в класс Point, использованный в предыдущих примерах. Метод distance принимает в качестве параметра еще один объект Point, вычисляет евклидово расстояние между двумя точками и возвращает результат в виде вещественного значения с двойной точностью:

public double distance(Point that) {

double xdiff, ydiff; xdiff = x — that.x; ydiff = y — that.y;

return Math.sqrt(xdiff * xdiff + ydiff * ydiff);

}

Для объектов lowerLeft и upperRight, которые были определены в разделе, посвященном созданию экземпляров объектов, вызов метода distance может выглядеть так:

double d = lowerLeft.distance(upperRight);

После выполнения этого оператора переменная d будет содержать евклидово расстояние между точками lowerLeft и upperRight.

1.7.2. Ссылка this

Иногда объекту-получателю бывает необходимо знать ссылку на самого себя. Например, объект-получатель  может захотеть внести себя в какой-нибудь список объектов. В каждом методе может использоваться this — ссылка на текущий объект (объект-получатель). Следующее определение clear эквивалентно приведенному выше:

public void clear() { this.x = 0; this.y = 0;

}

Ссылка this часто используется в качестве параметра для тех методов, которым нужна ссылка на объект. Кроме того, this также может применяться для именования членов текущего объекта. Вот еще один из методов Point, который называется move и служит для присвоения полям x и y определенных значений:

public void move(double x, double y) {

this.x = x;

this.y = y;

}

В методе move ссылка this помогает разобраться, о каких x и y идет речь. Присвоить аргументам move имена x и y вполне разумно, поскольку в этих параметрах методу передаются координаты x и y точки. Но тогда получается, что имена параметров совпадают с именами полей Point, и имена параметров скрывают имена полей. Если бы мы просто написали x = x, то значение параметра x было бы присвоено самому параметру, а не полю x, как мы хотели. Выражение this.x определяет поле x объекта, а не параметр x метода move.

1.7.3. Статические методы

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

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

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

В реализации метода distance из предыдущего примера использован статический метод Math.sqrt для вычисления квадратного корня. Класс Math содержит множество методов для часто встречающихся математических  операций. Эти методы объявлены

статическими, так как они работают не с каким-то определенным объектом, но составляют внутри класса группу со сходными функциями.

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

1.8. Массивы

Простые переменные, содержащие всего одно значение, полезны, но для многих приложений их недостаточно. Скажем, для разработки программы игры в карты требуется множество объектов Card, с которыми можно было бы оперировать как с единым целым. Для таких случаев в языке Java предусмотрены массивы.

Массивом называется набор переменных, относящихся к одному типу. Доступ к элементам массива осуществляется посредством простых целочисленных индексов. В карточной игре объект Deck (колода) может выглядеть так:

class Deck {

final int DECK_SIZE = 52;

Card[] cards = new Card[DECK_SIZE];

public void print() {

for (int i = 0; i < cards.length; i++) System.out.println(cards[i]);

}

}

Сначала мы объявляем константу с именем DECK_SIZE, содержащую количество кард в колоде. Затем поле cards объявляется в виде массива типа Card — для этого после имени типа в объявлении необходимо поставить квадратные скобки [ и ]. Размер массива определяется при его создании и не может быть изменен в будущем.

Вызов метода print показывает, как производится доступ к элементам массива: индекс нужного элемента заключается в квадратные скобки [ и ], следующие за именем массива.

Как нетрудно догадаться по тексту программы, в объекте-массиве имеется поле length, в котором хранится количество элементов в массиве. Границами массива являются целые числа 0 и length-1. Если попытаться обратиться к элементу массива, индекс которого выходит за эти пределы, то возбуждается исключение IndexOutOfBounds.

В этом примере также демонстрируется новый механизм объявления переменных — переменная цикла объявлена в секции инициализации цикла for. Объявление переменной в секции инициализации — удобный и наглядный способ объявления простой переменной цикла. Такая конструкция допускается лишь при инициализации цикла for; вы не сможете объявить переменную при проверке условия в операторе if или while.

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

операторах цикла.

Упражнение 1.8

Измените приложение Fibonacci так, чтобы найденные числа Фибоначчи сохранялись в массиве и выводились в виде списка значений в конце программы.

Упражнение 1.9

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

Источник: Арнольд К., Гослинг Д. – Язык программирования Java (1997)

По теме:

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