从您的评论回复看来,您可能不明白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;
}
}
}
现在,我可以使用static 方法调用表单(类名+方法名)的静态工厂方法创建一个新的Dice:
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() 将不起作用,因为必须针对实例调用 roll 方法,以便它知道要为多少边(在这种情况下)进行滚动。
更高级的主题:该静态方法是一个工厂,可以根据边数创建具有不同特征/随机性的子类。例如,稍后我可以创建一个名为 TrickDice 的特殊 Dice 子类,并且任何时候有人要求一个 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 方法的有效用法之一。同样,虽然不要过度使用静态方法,但在学习语言时尽量使用普通方法。
编辑:我在另一个question 中注意到您使用此方法签名:
public static void printDice (Dice Dice)
在这里,您使用相同的字母大小写命名了类和变量。我在这个问题中解决了这个问题,因为这可能会帮助您解决您在此处表达的一些困惑。您应该注意用于类和变量的名称。奇怪的是,Java 实际上接受了这种语法。第一个Dice 是类名(类型),第二个Dice 是参数名。相反,您应该为变量/参数名称使用小写字母,因此它应该如下所示:
public static void printDice (Dice dice)
那么当您使用对象引用 (dice) 或类名 (Dice) 时,方法内会更加清晰。
另外,这个打印方法可能应该是Dice 类的一个方法。使用 OOP,您应该考虑要求对象自行打印。这允许不同的子类提供不同的方式来打印自己,而无需尝试将所有逻辑放在一个方法中。这是一个过度使用静态方法的例子,它会降低类的价值和灵活性。