匿名类变成了内部类

时间:2011-02-17 00:39:00

标签: java

我被要求将匿名按钮类转换为内部按钮类。我要阅读的文本使用包含ActonListener的示例讨论了该主题。但是,我要求修改的代码中没有ActonListener。所以我很难遵循我应该做的事情。如何使用以下代码并将匿名转换为内部类。我的按钮代码甚至还有一个匿名类吗?

警告:不要只为我打一个答案。我需要学习这个。请指点我正确的方向。

这是我的代码:

package ui.panels;

import java.awt.Panel;

import interfaces.Resettable;
import model.Model;
import ui.panels.ButtonPanel;

public class ControlsPanel extends Panel implements Resettable{  
    private ButtonPanel btnPanel;

    public ControlsPanel (Model model) {
        btnPanel = new ButtonPanel(model);
        add(btnPanel);
    }

    public void resetComponents() {
    }
}

这是“ButtonPanel.java”

package ui.panels;

import java.awt.Button;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import model.Model;

public class ButtonPanel extends Panel {
  private Button btnClear;

    public ButtonPanel(final Model model) {
        btnClear = new Button("Clear");
        btnClear.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                model.resetComponents();
                model.repaint();
            }
        });
        add(btnClear);
    }
}

6 个答案:

答案 0 :(得分:4)

该按钮不是匿名的,但是动作监听器是。具体做法是:

btnClear.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent arg0) {
        model.resetComponents();
        model.repaint();
    }
});

在这里,您调用方法addActionListener,并作为参数传递ActionListener的实现。这里的关键是这个实现是一个匿名类,它实现了内联接口。

请记住,ActionListener是一个接口,接口不能包含实际的实现。相反,正在发生的是,正在声明一个新类(没有名称)实现 ActionListener。该接口定义了一个方法actionPerformed,它是按钮的实际处理程序 - 它调用resetComponentsrepaint。可以通过实现ActionListener将其转换为实际具有名称的新普通类,继续实施actionPerformed

答案 1 :(得分:1)

啊哈!我认为匿名类实际上是在“ButtonPanel.java”中!我花了好几个小时看错了文件!

答案 2 :(得分:0)

确实,那里没有匿名课程。人们可以想象以另一种方式运行的变换,例如新的Resettable()....

答案 3 :(得分:0)

---编辑为问题已更新---

btnClear.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                model.resetComponents();
                model.repaint();
            }
        });

包含一个从ActionListener

扩展的匿名类

您需要使用该代码来读取类似

的内容
btnClear.addActionListener(new MyInnerClass());

如果你这样做,100%相同的一切工作,我会说你做到了!

---原帖如下--- 问题的措辞是这样的,我可能会理解它;但是,我不确定。

一个暗示是它要求内部阶级。这意味着解决方案希望您编写内部类:

public class ControlsPanel extends Panel implements Resettable {

    // must have an inner class
    class SomeButtonModel (or SomeButtonPanel) {
       // code for inner class.
    }

}

请注意,如果您通过在初始化程序块中指定缺少的函数找到在代码中实例化的抽象类(或接口),则可能找到了“匿名”类。这意味着你的内部类应该扩展那个特定的类,你应该重新设计问题以使用你的内部类而不是匿名构造。

与往常一样,主要问题是最初了解所提出的问题,一旦完成,剩下的就是工作。

答案 4 :(得分:0)

根据我的看法,ButtonPanel是非标准的,所以如果没有进一步的信息,每个答案都会很难,但我可以提供一些默认答案; - )

“我的按钮代码中是否还有一个匿名类?” 不,不。如果您想要实现特定接口的类的实例,则通常会创建匿名类。

非GUI示例将是比较器。您希望在特定条件之后比较数组 - 您可以为此创建一个额外的类,但无论如何您只能使用它一次并且没有真正的可重用性。因此,我们将创建一个实现Comparator接口的匿名类:

    Comparator<Integer> c = new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            return o1 - o2;
        }
    };

没有什么特别之处 - 请注意,您的匿名类可以访问外部变量,但在创建对象时会复制它们。为避免混淆,这意味着局部变量必须是最终的。

答案 5 :(得分:0)

使用匿名类的一个示例是“动态”实现ActionListener接口,而不是定义单独的类(即具有名称的类,因此匿名)。例如:

JButton jb = new JButton("click me");
jb.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {
          // do stuff
     }
});

“new ActionListener()”类是匿名的,因为它没有名称。

要将ActionListener创建为外部类(称为OuterClass)中的内部类,您可以这样说:

public class OuterClass {
    public OuterClass() {
        JButton jb = new JButton("click me");
        jb.addActionListener(new MyActionListener());
    }

    private class MyActionListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
          // do stuff
        }
    } // end inner class

} // end outer class

现在代替匿名类,你有一个命名的内部类,即“MyActionListener。”

希望有所帮助

-Ed