Методы в Java создаются только как части класса. Метод может вызываться только для объекта6, и этот объект должен обладать возможностью произвести такой вызов. Если вы попытаетесь вызвать для объекта несуществующий метод, то получите ошибку компиляции. Вызов метода осуществляется следующим образом: сначала записывается имя объекта, за ним точка, за ней следуют имя метода и его список аргументов:
имяОбъекта.имяМетода(арг1. арг2, аргЗ)
Например, представьте, что у вас есть метод f(), вызываемый без аргументов, который возвращает значение типа int. Если у вас имеется в наличии объект а, для которого может быть вызван метод f(), в вашей власти использовать следующую конструкцию:
int х = a.f(),
Тип возвращаемого значения должен быть совместим с типом х.
Такое действие вызова метода часто называется
Список аргументов
Список аргументов определяет, какая информация передается методу. Как легко догадаться, эта информация — как и все в Java — воплощается в форме объектов, поэтому в списке должны быть указаны как типы передаваемых объектов, так и их имена. Как и в любой другой ситуации в Java, где мы вроде бы работаем с объектами, на самом деле используются ссылки2. Впрочем, тип ссылки должен соответствовать типу передаваемых данных. Если предполагается, что аргумент является строкой (то есть объектом String), вы должны передать именно строку, или ожидайте сообщения об ошибке.
Рассмотрим метод, получающий в качестве аргумента строку (String). Следующее определение должно размещаться внутри определения класса, для которого создается метод:
int storage(String s) {
return s.lengthO * 2;
}
Метод указывает, сколько байтов потребуется для хранения данных определенной строки. (Строки состоят из символов char, размер которых — 16 бит, или 2 байта; это сделано для поддержки набора символов Unicode.) Аргумент имеет тип String и называется s. Получив объект s, метод может работать с ним точно так же, как и с любым другим объектом (то есть посылать ему сообщения). В данном случае вызывается метод length(), один из методов класса String; он возвращает количество символов в строке.
Также обратите внимание на ключевое слово return, выполняющее два действия. Во-первых, оно означает: «выйти из метода, все сделано». Во-вторых, если метод возвращает значение, это значение указывается сразу же за командой return. В нашем случае возвращаемое значение — это результат вычисления s.length() * 2.
Метод может возвращать любой тип, но, если вы не хотите пользоваться этой возможностью, следует указать, что метод возвращает void. Ниже приведено несколько примеров:
boolean flagO { return true: }
float naturalLogBaseO { return 2.718, }
void nothingO { return; }
void nothing2() {}
Когда выходным типом является void, ключевое слово return нужно лишь для завершения метода, поэтому при достижении конца метода его присутствие необязательно. Вы можете покинуть метод в любой момент, но если при этом указывается возвращаемый тип, отличный от void, то компилятор заставит вас (сообщениями об ошибках) вернуть подходящий тип независимо от того, в каком месте метода было прервано выполнение.
К этому моменту может сложиться впечатление, что программа — это просто «свалка» объектов со своими методами, которые принимают другие объекты в качестве аргументов и посылают им сообщения. По большому счету так оно и есть, но в следующей главе вы узнаете, как производить кропотливую низкоуровневую работу с принятием решений внутри метода. В этой главе достаточно рассмотрения на уровне посылки сообщений.
Создание программы на Java
Есть еще несколько вопросов, которые необходимо понять перед созданием первой программы на Java.
Создание программы на Java
Видимость имен
Проблема управления именами присуща любому языку программирования. Если имя используется в одном из модулей программы и оно случайно совпало с именем в другом модуле у другого программиста, то как отличить одно имя от другого и предотвратить их конфликт? В С это определенно является проблемой, потому что программа с трудом поддается контролю в условиях «моря» имен. Классы С-и- (на которых основаны классы Java) скрывают функции внутри классов, поэтому их имена не пересекаются с именами функций других классов. Однако в С++ дозволяется использование глобальных данных и глобальных функций, соответственно, конфликты полностью не исключены. Для решения означенной проблемы в С++ введены