简体   繁体   English

Java中的内部类

[英]Inner Classes in Java

I am making a keyboard-like buttons for my Hangman game ( SEE PICTURE HERE ), my problem is about the inner classes. 我正在为我的Hangman游戏制作类似键盘的按钮( 参见图片 ),我的问题是关于内部课程。 I've read this LINK about inner classes and it says that you can only access the outside variables with FINAL type. 我已经阅读了关于内部类的LINK ,它说你只能使用FINAL类型访问外部变量。 But if I declared the variable as such, I cannot change the value of it anymore... So my problem is that I need to change the value inside the inner class. 但是如果我这样声明变量,我就不能再改变它的值......所以我的问题是我需要改变内部类中的值。 My code is as follows: 我的代码如下:

public class MainGame extends JDialog {

    private String player;
    private char [] wordChar;
    private JButton[] buttons;
    private int level;
    private int score;
    private int livesLeft;
    private int missedGuess;

 void newGame() {

        level = 0;
        score = 0;
        livesLeft = 10;
        missedGuess = 0;

       //label1:
       // while (livesLeft!= 0) {

            //get random WORD from LIST
            Word hiddenWord = new Word();

            //put random word in Array
            wordChar = new char[hiddenWord.getHiddenWord().length()];
            wordChar = hiddenWord.getHiddenWord().toCharArray();

            buttons = new JButton[wordChar.length];
            for (int i = 0; i < wordChar.length; i++){
                JButton guessWord = new JButton(" ");
                guessWord.setFont(new Font("Microsoft Sans Serif", 1, 18));
                guessWord.setEnabled(false);

                jPanel3.setLayout(new GridLayout(1, wordChar.length));
                jPanel3.add(guessWord);

                buttons[i] = guessWord;
            }
      checkLetter();
      }

    void checkLetter() {
         int checker = 0;
         while(checker != wordChar.length){
            jPanel1.setLayout(new GridLayout(3, 9, 3, 5));
            for (char buttonChar = 'a'; buttonChar <= 'z'; buttonChar++) {
                String buttonText = String.valueOf(buttonChar);
                final JButton letterButton = new JButton(buttonText);
                letterButton.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        String actionCommand = e.getActionCommand();
                        for (int j = 0; j < wordChar.length; j++){
                            String text =  String.valueOf(wordChar[j]);
                            if(actionCommand.equals(text)){
                                buttons[j].setText(text);
                                checker++; //THIS CODE IS NOT POSSIBLE!!!!
                            }
                        }
                    }
                });
                jPanel1.add(letterButton);
             }
               checker++;
          }
        }

NOTE: The code above is not complete. 注意:上面的代码不完整。 The int checker is used to count how many correct letters are already guessed so that if it is equal to the length of the word, I can now proceed to the next level int检查器用于计算已经猜到多少个正确的字母,这样如果它等于单词的长度,我现在可以进入下一个级别 在此输入图像描述

How can I re-do my code? 我该如何重新编写代码?

You can declare checker as a field of outer class, and access it with some method, something like increaseChecker() . 您可以将checker声明为外部类的字段,并使用某种方法访问它,例如increaseChecker()

UPDATE: Something like this: 更新:这样的事情:

1) Create checker field in outer class: 1)在外部类中创建检查器字段:

public class OuterClassName {
    private int checker;

    protected void increaseChecker() {
        checker++;
    }

    void checkLetter() {
        // ...
    }

}

2) Use increaseChecker() method call instead of checker++ 2)使用increaseChecker()方法调用而不是checker++

You can't access local variables in an anonymous inner class, and that's for a good reason. 您无法访问匿名内部类中的局部变量,这是有充分理由的。 The actionPerformed() method isn't guaranteed to be called inside the checkLetter() function. 不保证在checkLetter()函数内调用actionPerformed()方法。 It will be called later, possibly (and most probably) after the function exits so its local variables will be destroyed by that time. 稍后将调用它,可能(并且很可能)在函数退出之后调用,因此它的局部变量将在那时被销毁。 Therefore, the newly created anonymous class implicitly gets a copy of that variable. 因此,新创建的匿名类隐式获取该变量的副本。 But it wouldn't make any sense to increase the copy, that's why only final local variables can be accessed from methods of an anonymous class. 但是增加副本没有任何意义,这就是为什么只能从匿名类的方法访问最终的局部变量。

The simplest workaround is just to make checker a field of the outer class. 最简单的解决方法是使checker成为外部类的字段。 But that wouldn't make any sense if it's accessed only within the checkLetter() function unless it is necessary for it to retain its value between checkLetter() calls. 但是,如果仅在checkLetter()函数中访问它,那将毫无意义,除非它必须在checkLetter()调用之间保留其值。 In order to find out the true answer, you need to think why you are trying to increase checker inside actionPerformed()? 为了找到真正的答案,你需要考虑为什么你要在actionPerformed()中增加checker When should it happen and what are you trying to achieve by doing it? 什么时候应该发生?你想通过做什么来实现?

Why not keep the anonymous inner class but have it call a method of the class. 为什么不保留匿名内部类,但让它调用类的方法。 This way final isn't an issue. 这样决赛不是问题。

            letterButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    letterButtonActionPerformed(e); // create this method
                }
            });


            //.....


            // new method
            private void letterButtonActionPerformed(ActionEvent e) {
                    String actionCommand = e.getActionCommand();
                    for (int j = 0; j < wordChar.length; j++){
                        String text =  String.valueOf(wordChar[j]);
                        if(actionCommand.equals(text)){
                            buttons[j].setText(text);
                            checker++; //THIS CODE IS NOT POSSIBLE!!!!
                        }
                    }
            }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM