【问题标题】:How can I rewrite an anonymous Java class into a non-anonymous class?如何将匿名 Java 类重写为非匿名类?
【发布时间】:2013-09-03 14:34:56
【问题描述】:

了解匿名类并从 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 指定了当您选择说“Hello World”按钮时会发生什么。此方法需要 EventHandler 类型的对象。 EventHandler 接口只包含一个方法,handle。 该示例没有使用新类实现此方法,而是使用匿名类表达式。请注意,此表达式是传递给 btn.setOnAction 方法的参数。

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

【问题讨论】:

  • 考虑一下普通顶级类和匿名类的区别和相似之处。
  • @LuiggiMendoza 我不知道该怎么办。
  • 真的……只是新建一个类实现EventHandler,没看到问题抱歉
  • 在我的 IDE 中,我点击 F6 进行移动,它建议了一个名称。不需要比这更难。
  • “非匿名类”到底是什么意思?最接近匿名类的是命名本地类(local = inside a method);将其转换为所需的努力最少。然后,您还可以有一个非本地内部类,即一个是内部类但不在方法内部的类。转换到那个需要稍微多一点的努力。最后,你有一个静态的内部类或成熟的顶级类;转换到那个需要最大的努力。

标签: java anonymous-class


【解决方案1】:

只需在某处创建一个新的非匿名类。我将其作为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!");
        }
    }
}

【讨论】:

  • 所以您不必将 MyEventHandler 类放在另一个文件中?或者如果你这样做了,你会只使用 import 吗?
  • 不,这不是必需的。如果你愿意,你可以这样做。我选择制作一个嵌套类文件,以保持答案简短。
【解决方案2】:

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
        }
    }
}

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

【讨论】:

    【解决方案3】:

    我不知道该怎么办。

    1. 创建一个实现所需接口的新类。1
    2. 将代码从匿名类移到新类。
    3. 无论在何处使用您的匿名类,都可以将其更改为此类的新实例。

    将此应用于提供的示例:

    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:请注意,实现接口的类将遵循您编写的任何简单类的规则,这意味着它可以是顶级类、内部类或staticinner 类。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-07
      • 1970-01-01
      • 2013-02-15
      • 1970-01-01
      相关资源
      最近更新 更多