Члены класса
Методы и переменные, которые мы имеем в классе Adult , являются методами и переменными экземпляра. Каждый экземпляр будет их иметь.
Классы сами по себе тоже могут иметь переменные и методы. Они в совокупности называются членами класса, и вы можете объявить их при помощи ключевого слова static . Различия между членами класса и методами и переменными экземпляра таковы:
- Каждый экземпляр класса совместно использует одну и ту же копию переменной класса.
- Вы можете вызвать метод класса с самим классом, без наличия экземпляра.
- Методы экземпляра могут обращаться к переменным класса, но методы класса не могут обращаться к переменным экземпляра.
- Методы класса могут обращаться только к переменным класса.
Когда имеет смысл добавить переменные класса или методы класса? Лучшее практическое правило — делать это редко, для того чтобы не злоупотреблять ими. Некоторыми обычными примерами их использования являются:
- Объявление констант, которыми могут пользоваться любые экземпляры класса.
- Отслеживание «счетчика» экземпляров класса.
- Использование в классе со вспомогательными методами, которые для своей работы не требуют наличия экземпляра (например, метод Collections.sort()).
Переменные класса
Для создания переменной класса используйте ключевое слово static при ее объявлении:
accessSpecifier static variableName [= initialValue ];
JRE создает копию переменных экземпляра класса для каждого экземпляра этого класса. JRE создает только одну копию каждой переменной класса независимо от количества экземпляров сразу при первой встрече с этим классом в программе. Все экземпляры будут совместно использовать (и, возможно, изменять) эту копию. Это делает переменные класса хорошим выбором для констант, которые могут использовать все экземпляры.
Например, мы использовали целые числа для описания «банкнот» в кошельке Adult . Это совершенно корректно, но, возможно, было бы правильнее поименовать целочисленные значения таким образом, чтобы мы при чтении кода легко видели, что означают числа. Объявим для этого несколько констант в том же месте, где мы объявили переменные экземпляра для нашего класса:
protected static final int ONE_DOLLAR_BILL = 1; protected static final int FIVE_DOLLAR_BILL = 5; protected static final int TEN_DOLLAR_BILL = 10; protected static final int TWENTY_DOLLAR_BILL = 20; protected static final int FIFTY_DOLLAR_BILL = 30; protected static final int ONE_HUNDRED_DOLLAR_BILL = 40;
По соглашению константы класса называются большими символами, отдельные слова констант разделяются знаками подчеркивания. Мы использовали ключевое слово static для объявления их в качестве переменных класса и добавили ключевое слово final , чтобы гарантировать невозможность их изменения каким-либо экземпляром (то есть, сделать их константами). Теперь мы можем изменить метод main() для добавления денег в наш объект Adult при помощи этих новых констант:
public static void main(String[] args) { Adult myAdult = new Adult(); myAdult.addMoney(new int[] { Adult.ONE_DOLLAR_BILL, Adult.FIVE_DOLLAR_BILL }); System.out.println(myAdult); }
При чтении кода очевидно, что мы добавляем деньги в кошелек.
Методы класса
Как мы уже видели, вызов метода экземпляра осуществляется следующим образом:
variableWithInstance.methodName();
Мы вызвали метод именованной переменной, хранящей экземпляр класса. Вызов метода класса осуществляется следующим образом:
ClassName.methodName();
Нам не нужен экземпляр для вызова этого метода. Для этого применяется сам класс. Используемый нами метод main() является методом класса. Взгляните на его сигнатуру. Обратите внимание на то, что он объявлен как public static . Мы видели этот спецификатор доступа прежде. Ключевое слово static указывает, что это метод класса, вот почему такие методы иногда называются статическими методами. Нам не нужен экземпляр Adult для вызова main() .
Мы можем создать методы класса для Adult при желании, хотя в действительности нет причины делать это в данном случае. Хотя для демонстрационных целей добавим тривиальный метод класса:
public static void doSomething() { System.out.println("Did something"); }
Закомментируйте имеющиеся строки кода в методе main() и добавьте следующие строки:
Adult.doSomething(); Adult myAdult = new Adult(); myAdult.doSomething();
После выполнения этого кода вы должны увидеть соответствующее сообщение, дважды отображенное на консоли. Первый вызов doSomething() является обычным способом вызова метода класса. Можно также вызвать его через экземпляр класса, как это сделано в третьей строке кода.
Но это, в действительности, не очень хорошая практика. Eclipse предупредит об этом, подчеркнув эту строку желтой волнистой линией, и предложит обратиться к этому методу «статическим способом» через класс, а не через экземпляр.