Из ответов на ваши комментарии следует, что вы можете не понимать разницу между static
и нестатическими методами.
Чтобы вызвать статический метод, вы используете класс и имя метода. Давайте возьмем слегка измененный пример:
public class Dice {
private static final Random RANDOM = new Random();
private int sides;
protected Dice(int sides) {
this.sides = sides;
}
public static Dice create(int sides) {
return new Dice(sides);
}
public int roll() {
synchronized(RANDOM) {
return RANDOM.nextInt(sides) + 1;
}
}
}
Теперь я могу создать новый Dice
, используя метод статической фабрики, используя форму вызова метода static
(имя класса + имя метода):
Dice d = Dice.create(6);
Но для обычных методов вы вызываете их в отношении экземпляра объекта, потому что они могут работать с данными, хранящимися в этом объекте. В этом случае я создал объект, который содержится в ссылочной переменной d
, и этот объект содержит число сторон, для которых он должен сгенерировать число. Чтобы позвонить, используйте:
int value = d.roll();
Существует много преимуществ использования обычных методов по сравнению со статическими. Не злоупотребляйте static
методами. Статические методы не наследуются и не являются частью объекта - они просто считаются частью класса. Вот почему вы вызываете статические методы, используя имя класса (хотя Java, к сожалению, также допускает использование object.method, но хорошая IDE предупредит вас об этом). Нет связанного состояния памяти. Однако сам объект также имеет состояние памяти, и может быть много разных экземпляров класса с разными значениями. Здесь мы могли бы создать разные двусторонние кости:
Dice six = Dice.create(6);
Dice twenty = Dice.create(20);
// Use the dice for a 1D6 + 1D20 roll.
int value = six.roll() + twenty.roll();
В этом примере я вызвал метод roll
для двух разных экземпляров объекта. Использование Dice.roll()
не сработает, так как метод крена должен быть вызван по отношению к экземпляру, чтобы он знал, сколько сторон (в данном случае) нужно выполнить крен.
Более продвинутая тема: этот статический метод является фабричным и может создавать подклассы, которые имеют разные особенности / случайность в зависимости от количества сторон. Например, позже я мог создать специальный подкласс игры в кости под названием TrickDice, и каждый раз, когда кто-то запрашивал 5-стороннюю игру в кости, он получал одну из них, просто изменяя метод create
:
public static Dice create(int sides) {
if (sides == 5)
return new TrickDice(5);
else
return new Dice(sides);
}
Это не меняет того, как оно называется ...
Dice d = Dice.create(5); // This really is a TrickDice
Это одно из допустимых применений метода static
. Опять же, хотя и не злоупотребляйте статическими методами, старайтесь использовать как можно больше обычных методов при изучении языка.
РЕДАКТИРОВАТЬ : я заметил в другом вопросе , что вы используете этот метод подписи:
public static void printDice (Dice Dice)
Здесь вы назвали класс и переменную, используя один и тот же регистр букв. Я расскажу об этом здесь в этом вопросе, потому что это может помочь вам в некоторой путанице, которую вы выразили здесь. Вы должны быть осторожны с именами, которые вы используете для своих классов и переменных. Странно, но на самом деле Java принимает этот синтаксис. Первый Dice
- это имя класса (тип), а второй Dice
- это имя параметра. Вместо этого вы должны использовать строчные буквы для имени переменной / параметра, поэтому оно должно выглядеть так:
public static void printDice (Dice dice)
Тогда в методе будет более понятно, когда вы используете ссылку на объект (dice
) или имя класса (Dice
).
Кроме того, этот метод печати, вероятно, должен быть методом класса Dice
. С ООП вы должны подумать о том, чтобы попросить объект напечатать сам. Это позволяет различным подклассам предоставлять разные способы печати, не пытаясь объединить всю логику в одном методе. Это пример чрезмерного использования статического метода, который снижает ценность и гибкость ваших классов.