博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java™ 教程(匿名类)
阅读量:6823 次
发布时间:2019-06-26

本文共 6376 字,大约阅读时间需要 21 分钟。

匿名类

匿名类可以使你代码更简洁,它们使你能够同时声明和实例化一个类,它们就像局部类,除了它们没有名称,如果你只需要使用局部类一次,请使用它们。

声明匿名类

虽然局部类是类声明,但匿名类是表达式,这意味着你在另一个表达式中定义该类,以下示例HelloWorldAnonymousClasses在局部变量frenchGreetingspanishGreeting的初始化语句中使用匿名类,但使用局部类初始化变量englishGreeting

public class HelloWorldAnonymousClasses {      interface HelloWorld {        public void greet();        public void greetSomeone(String someone);    }      public void sayHello() {                class EnglishGreeting implements HelloWorld {            String name = "world";            public void greet() {                greetSomeone("world");            }            public void greetSomeone(String someone) {                name = someone;                System.out.println("Hello " + name);            }        }              HelloWorld englishGreeting = new EnglishGreeting();                HelloWorld frenchGreeting = new HelloWorld() {            String name = "tout le monde";            public void greet() {                greetSomeone("tout le monde");            }            public void greetSomeone(String someone) {                name = someone;                System.out.println("Salut " + name);            }        };                HelloWorld spanishGreeting = new HelloWorld() {            String name = "mundo";            public void greet() {                greetSomeone("mundo");            }            public void greetSomeone(String someone) {                name = someone;                System.out.println("Hola, " + name);            }        };        englishGreeting.greet();        frenchGreeting.greetSomeone("Fred");        spanishGreeting.greet();    }    public static void main(String... args) {        HelloWorldAnonymousClasses myApp =            new HelloWorldAnonymousClasses();        myApp.sayHello();    }            }

匿名类的语法

如前所述,匿名类是表达式,匿名类表达式的语法类似于构造函数的调用,除了代码块中包含类定义。

考虑frenchGreeting对象的实例化:

HelloWorld frenchGreeting = new HelloWorld() {     String name = "tout le monde";     public void greet() {          greetSomeone("tout le monde");     }     public void greetSomeone(String someone) {         name = someone;         System.out.println("Salut " + name);     }};

匿名类表达式包含以下内容:

  • new运算符。
  • 要实现的接口的名称或要继承的类,在此示例中,匿名类正在实现接口HelloWorld
  • 包含构造函数参数的圆括号,就像普通的类实例创建表达式一样,注意:实现接口时,没有构造函数,因此你使用一对空括号,如本例所示。
  • 类声明体,更具体地说,类体中,方法声明是允许的,但语句不是。

因为匿名类定义是表达式,所以它必须是语句的一部分,在此示例中,匿名类表达式是实例化frenchGreeting对象的语句的一部分(这解释了为什么在闭合花括号后有一个分号)。

访问封闭范围的局部变量,以及声明和访问匿名类的成员

与局部类一样,匿名类可以,它们对封闭范围的局部变量具有相同的访问权限:

  • 匿名类可以访问其封闭类的成员。
  • 匿名类无法访问其封闭范围中未声明为final或者实际为final的局部变量。
  • 与嵌套类一样,匿名类中的类型(例如变量)的声明会影响封闭范围中具有相同名称的任何其他声明,有关更多信息,请参阅。

匿名类对其成员也具有与局部类相同的限制:

  • 你不能在匿名类中声明静态初始化或成员接口。
  • 匿名类可以具有静态成员,前提是它们是常量变量。

请注意,你可以在匿名类中声明以下内容:

  • 字段
  • 额外的方法(即使他们没有实现超类型的任何方法)
  • 实例初始化
  • 局部类

但是,你不能在匿名类中声明构造函数。

匿名类的示例

匿名类通常用于图形用户界面(GUI)应用程序。

考虑JavaFX示例HelloWorld.java(来自Hello World的部分,来自JavaFX入门的JavaFX样式),此示例创建一个包含Say 'Hello World'按钮的frame:

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
() { @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<ActionEvent>类型的对象,EventHandler<ActionEvent>接口只包含一个方法handle。该示例使用匿名类表达式,而不是使用新类实现此方法,请注意,此表达式是传递给btn.setOnAction方法的参数。

因为EventHandler<ActionEvent>接口只包含一个方法,所以可以使用lambda表达式而不是匿名类表达式,有关更多信息,请参阅Lambda表达式一节。

匿名类是实现包含两个或更多方法的接口的理想选择,以下JavaFX示例来自部分,匿名类代码创建一个只接受数值的文本字段,它通过重写从TextInputControl类继承的replaceTextreplaceSelection方法,使用匿名类重新定义TextField类的默认实现。

import javafx.application.Application;import javafx.event.ActionEvent;import javafx.event.EventHandler;import javafx.geometry.Insets;import javafx.scene.Group;import javafx.scene.Scene;import javafx.scene.control.*;import javafx.scene.layout.GridPane;import javafx.scene.layout.HBox;import javafx.stage.Stage;public class CustomTextFieldSample extends Application {        final static Label label = new Label();     @Override    public void start(Stage stage) {        Group root = new Group();        Scene scene = new Scene(root, 300, 150);        stage.setScene(scene);        stage.setTitle("Text Field Sample");         GridPane grid = new GridPane();        grid.setPadding(new Insets(10, 10, 10, 10));        grid.setVgap(5);        grid.setHgap(5);         scene.setRoot(grid);        final Label dollar = new Label("$");        GridPane.setConstraints(dollar, 0, 0);        grid.getChildren().add(dollar);                final TextField sum = new TextField() {            @Override            public void replaceText(int start, int end, String text) {                if (!text.matches("[a-z, A-Z]")) {                    super.replaceText(start, end, text);                                     }                label.setText("Enter a numeric value");            }             @Override            public void replaceSelection(String text) {                if (!text.matches("[a-z, A-Z]")) {                    super.replaceSelection(text);                }            }        };         sum.setPromptText("Enter the total");        sum.setPrefColumnCount(10);        GridPane.setConstraints(sum, 1, 0);        grid.getChildren().add(sum);                Button submit = new Button("Submit");        GridPane.setConstraints(submit, 2, 0);        grid.getChildren().add(submit);                submit.setOnAction(new EventHandler
() { @Override public void handle(ActionEvent e) { label.setText(null); } }); GridPane.setConstraints(label, 0, 1); GridPane.setColumnSpan(label, 3); grid.getChildren().add(label); scene.setRoot(grid); stage.show(); } public static void main(String[] args) { launch(args); }}

转载地址:http://pqrzl.baihongyu.com/

你可能感兴趣的文章
linux - command - iftop 磁盘IO查看神器
查看>>
腾讯MSDK支付接入记录
查看>>
Binary Tree Maximum Path Sum@LeetCode
查看>>
修改了一个HTML2Markdown 函数
查看>>
JXLS 2.4.0学习
查看>>
Android--listView长按修改ListView对象内容
查看>>
gradle_学习_02_gradle多模块构建实例
查看>>
Linux小技巧总结
查看>>
乾卦第一 坤卦第二
查看>>
Html2excel 1.4.1 发布,Html 转 Excel 工具包
查看>>
Linux安装配置反向代理Nginx
查看>>
Spring事务的传播属性和事务隔离级别
查看>>
精选10大机器学习开源项目 !(附链接)
查看>>
中国电信“商密云存储系统”通过国家商用密码产品鉴定
查看>>
用区块链技术养走地鸡,我认真的
查看>>
指数哥伦布编码
查看>>
mysql用SQLyog导入数据时报错(文件太大)
查看>>
Linux下查看用户列表
查看>>
svn图标显示问题
查看>>
卷积神经网络在图像分割中的进化史:从R-CNN到Mask R-CNN
查看>>