Вызовы методов
Объекты взаимодействуют путем передачи сообщений. Это значит, что объект может быть сконструирован так, чтобы демонстрировать определенное поведение как результат вызова соответствующей операции объекта. В Java это выполняется путем вызова метода объекта при помощи бинарного встроенного оператора точка «.». Вызов метода расшифровывает полное сообщение: объект-получатель сообщения, вызываемый метод и аргументы метода, если необходимо. Вызываемый метод получателя может также вернуть информацию отправителю через возвращаемое значение. Вызываемый метод должен быть одним из методов, определенных для объекта.
CharStack stack = new CharStack; //Создание стека
stack.push('J'); //(1) Символ 'J' помещается в стек
char с = stack.рор(); //(2) Один символ достаем и возвращаем: 'J'
stack. printStackElements(); //(3) Ошибка компиляции: нет такого метода в `CharStack`
Вышеприведенный фрагмент кода вызывает методы объекта, обозначенного ссылочной переменной stack
. Вызов метода в строке (1) помещает один символ в стек, а метод в строке (2) достает один символ из стека. Оба метода, push()
и pop()
, определены в классе CharStack
. Метод push()
не возвращает никакого значения, а метод pop()
возвращает изъятый символ. Попытка вызова метода printStackElements()
объекта стека приводит к ошибке компиляции, так как в классе CharStack
такой метод не определен.
Обозначение точка «.» также может использоваться со ссылкой для доступа к полям объекта. Использование обозначения точки регулируется доступностью членов. Так, поля класса CharStack
имеют уровень доступа private
, который показывает, что они недоступны извне класса.
stack.topOfStack++; //Ошибка компиляции: topOfStack - private-поле.
Статические члены
В некоторых случаях следует, чтобы некоторые члены принадлежали только классу и не были частью объекта, созданного из класса. Примером такой ситуации может быть случай, когда классу необходимо знать количество объектов, которые созданы на основе этого класса. Определение счетчика для отслеживания количества созданных объектов как переменной экземпляра не решает проблему. Каждый созданный объект будет иметь свое поле счетчика. Какой счетчик следует обновлять? Решение проблемы в том, чтобы объявить поле счетчика как static
(статическое). Такое поле называется статической переменной. Оно принадлежит классу, а не какому-то объекту класса. Статическая переменная инициализируется, когда загружается в память класс на этапе выполнения.
Таким образом, класс может иметь статические методы, которые принадлежат только классу, а не объектам класса.
Статические переменные и статические методы также известны как статические члены и отличаются от членов экземпляра в описании класса ключевым словом static
в своем объявлении.
На рис. 1.4 показана диаграмма класса CharStack
. Она дополнена двумя статическими членами, которые подчеркнуты. Дополненное описание класса CharStack
дается в примере 1.2. Поле счетчика объявлено как статическая переменная в строке (1). На этапе загрузки в память под него выделяется место, и оно инициализируется значением по умолчанию 0. Каждый раз, когда создается объект класса CharStack
, выполняется конструктор из строки (2). В конструкторе происходит явное увеличение счетчика класса. Метод getInstanceCount ()
в строке (3) — это статический метод, принадлежащий классу. При вызове он возвращает значение счетчика.
Рис. 1.4. Диаграмма класса, показывающая статические члены класса
Пример 1.2. Статические члены в описании класса
//Имя исходного файла CharStack.java
public class CharStack {
// Переменные экземпляра
private char[] stackArray; // Реализация массива стека,
private int topOfStack; // Вершина стека.
// Статическая переменная
private static int counter; // (1)
// Теперь конструктор увеличивает счетчик для каждого
// созданного объекта.
public CharStack(int capacity) { // (2)
stackArray = new char[capacity];
topOfStack = -1;
counter++;
}
// Методы экземпляра
public void push(char element){
stackArray[++topOfStack] = element;}
public char pop() { return stackArray[topOfStack--]; }
public char peek() { return stackArray[topOfStack]; }
public boolean isEmpty() { return topOfStack < 0; }
public boolean isFull(){
return topOfStack == stackArray.length -1;}
// Статический метод (3)
public static int getInstanceCount() { return counter; }
}
Клиенты могут обратиться к статическим членам класса, используя имя класса. Следующий код вызывает метод getInstanceCount()
класса CharStack
.
int count = CharStack.getInstanceCount(); //Имя класса для вызова статического метода
Статические члены также доступны через ссылки на объекты.
CharStack stack1 = new CharStack(10);
int count1 = stack1.getInstanceCount(); //Ссылка вызывает статический метод
Статические члены в классе могут быть доступны как по имени класса, так и через ссылки на объекты, но члены экземпляра могут быть доступны только через ссылки на объекты.