如何将匿名Java类重写为非匿名类?

时间:2013-09-03 14:34:57

标签: java anonymous-class

了解匿名类并从Oracle获得此知识。我希望有人能告诉我如果我不使用匿名课程会是什么样子。我怎么会用新班级做到这一点?

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class HelloWorld extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Hello World!");
        Button btn = new Button();
        btn.setText("Say 'Hello World'");
        btn.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                System.out.println("Hello World!");
            }
        });

        StackPane root = new StackPane();
        root.getChildren().add(btn);
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();
    }
}
  

在此示例中,方法调用btn.setOnAction指定选择Say“Hello World”按钮时发生的情况。此方法需要EventHandler类型的对象。 EventHandler接口只包含一个方法handle。 该示例使用匿名类表达式,而不是使用新类实现此方法。请注意,此表达式是传递给btn.setOnAction方法的参数。

来源:http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html

3 个答案:

答案 0 :(得分:3)

只需在某处创建一个新的非匿名类。我把它作为HelloWorld中的嵌套类:

public class HelloWorld extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Hello World!");
        Button btn = new Button();
        btn.setText("Say 'Hello World'");
        btn.setOnAction(new MyEventHandler());

        StackPane root = new StackPane();
        root.getChildren().add(btn);
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();
    }

    public class MyEventHandler implements EvenHandler<ActionEven>
    {
        @Override
        public void handle(ActionEvent event) {
            System.out.println("Hello World!");
        }
    }
}

答案 1 :(得分:1)

EventHandler类是无状态的,因此该类的所有实例在功能上都是等效的。我们只需要这个类的一个实例来执行handle操作,因为此方法的功能仅取决于传递给它的参数,它不依赖于对象的状态,因为它没有任何对象的状态。因此,它应该是一个单身人士。每次执行对setOnAction的调用时,使用匿名类将创建一个新实例。为避免这种情况,您可以考虑将EvenHandler实现的实例存储在私有静态final字段中,并使用静态工厂方法重用它,如下所示:

public class HandlerProvider{
private static final EvenHandler<ActionEvent> EVENT_HANDLER=new ActionEventHandler();

public static EvenHandler<ActionEvent> getEventHandler(){
return EVENT_HANDLER;
}
private static class ActionEventHandler implements EvenHandler<ActionEvent>
    {
        @Override
        public void handle(ActionEvent event) {
            //your action goes here
        }
    }
}

通过这种方式,您可以避免在每次方法调用时创建不必要的对象。

答案 2 :(得分:0)

  

我不知道该怎么做。

  1. 创建一个实现所需接口的新类。 1
  2. 将代码从匿名类移动到新类。
  3. 无论您使用匿名类,只需使用此类的新实例进行更改。
  4. 将此应用于提供的示例:

    class FooEventHandler implements EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            System.out.println("Hello World!");
        }
    }
    
    public class HelloWorld extends Application {
        //...
        @Override
        public void start(Stage primaryStage) {
            //...
            btn.setOnAction(new FooEventHandler());
            //...
        }
    }
    

    1 :请注意,实现接口的类将遵循您编写的任何简单类的规则,这意味着它可以是顶级类,内部类或{{1} } 内部类。