【问题标题】:Accessing public object variables访问公共对象变量
【发布时间】:2014-04-05 09:41:13
【问题描述】:

我正在编写一个井字游戏程序,我正在尝试在驱动程序中使用此类中的方法“playOn”,但我不确定我应该如何使用公共变量(X和 O)我已经定义使用该方法。它应该采用“单例”设计。任何帮助表示赞赏。

public class TTTPlayer {
    public TTTPlayer X = new TTTPlayer('X');
    public TTTPlayer O = new TTTPlayer('O');
    private char symbol;
    private Random gen;
    private boolean playerTurn; // true for 'X', false for 'O'

    private TTTPlayer(char ch) {
        this.symbol = ch;
    }
    public void playOn(TTTBoard board) {
        int row = gen.nextInt(2);
        int col = gen.nextInt(2);
    if (playerTurn) {
        board.place(X, row, col);
        playerTurn = false;
    } else {
        board.place(O, row, col);
        playerTurn = true;
   }
}

【问题讨论】:

  • 我会假设您与board.place(X, row,col);board.place(O, row, col); 完全一样。为什么 X 和 O 完全公开?
  • 好吧,为了确保没有其他 TTTPlayer 实例被创建,我的老师指定构造函数为私有并创建两个实例 X 和 O 公开,我不明白为什么,因为它只是让我更难使用它的方法。我不能在我的驱动程序中声明一个 TTTPlayer 实例,因为它是私有的,但我可以将它声明为这样的变量:“TTTPlayer player;”但我不能对它使用任何方法..
  • 嗯...如果它们被制作成public,那么我敢猜测它们将在定义它们的类之外使用。

标签: java oop singleton public


【解决方案1】:

我认为你在这里缺少的只是静态修饰符。

静态成员属于该类,它们以一种全局存在的方式存在(尽管它们不一定是全局可访问的)。您可以通过对类的引用来访问它们,例如 outSystem 类的静态成员,因此 System.out

当您使用new 创建一个新对象时,它是一个唯一的实例并且包含实例成员。 out 实际上是PrintStream 的对象实例,所以当你说out.println 时,println 是一个实例方法。

其他一些语言允许您在某种全局命名空间中声明函数和事物,但 Java 没有,所有东西都必须放在一个类中。所以我们有静态成员。

这里,XO 是像 System.out 这样的静态成员,但它们也是封闭类的实例。

public class TTTPlayer {
    private char symbol;

    private TTTPlayer(char ch) {
        this.symbol = ch;
    }

    public static TTTPlayer X = new TTTPlayer('X');
    public static TTTPlayer O = new TTTPlayer('O');
    private static Random gen;
    private static boolean playerTurn; // true for 'X', false for 'O'

    public static void playOn(TTTBoard board) {
        int row = gen.nextInt(2);
        int col = gen.nextInt(2);
        if (playerTurn) {
            board.place(X, row, col);
            playerTurn = false;
        } else {
            board.place(O, row, col);
            playerTurn = true;
        }
    }
}

要玩转牌,您可以致电TTTPlayer.playOn。同样,XO 使用类的名称访问,例如 TTTPlayer.XTTTPlayer.O

如果您对实例和静态之间的区别不满意(有些人不满意),请考虑将这两者分成不同的类。一个只用于令牌,另一个用于移动的静态成员。

【讨论】:

  • 我同意XO 应该是static。将playOn() 设为静态似乎是有问题的。
  • @Code-Guru 是的,它可以被重构,我假设你的意思是每个玩家都有自己的举动,但我真的不想推荐太多。它并没有像现在这样坏,所以在我的书中很好。
  • 啊,谢谢,我认为它与静态修饰符有关,但就像你说的,我对它的区别有点模糊。
  • 驱动的实际结构相当僵化,所以只要其他一切正常我就很高兴。
  • 我在我的答案中添加了一个静态/实例的说明性示例——我希望能有所帮助。 (我的评论太长了,反正答案更好。)
【解决方案2】:

首先,我同意@Radiodef 的观点,即应将XO 设为static。这将解决您的一些访问问题。

另外,在我看来,您有两个用于相同目的的变量:

private char symbol;

这包含一个XO 来指示玩家。

private boolean playerTurn;

评论明确指出,这也代表XO

我认为symbol 变量更有用,因为它包含转弯时要使用的确切字母。如果使用此变量,您可以大大简化 playOn() 方法,记住您将拥有两个 TTTPlayer 对象,每个对象都存储自己的 symbol 值。

最后,您还需要检查玩家是否没有尝试在已经占据的方格中移动。

【讨论】:

  • 是的.. 我确实看到了冗余。我尝试用“this.symbol == 'X'”替换布尔值,但 Eclipse 说它在静态上下文中不起作用。
【解决方案3】:

要有一个单身人士。您可以将构造函数设为私有并在私有静态字段中使用它:

private static MySingleton = new MySingleton();

然后提供一个访问器getMySingleton()

如果可以的话,也让玩家private 而不是public ;)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-20
    • 1970-01-01
    • 2018-11-27
    • 2012-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多