java 匿名内部类 Anonymous Classes

1、简介

匿名类是一个没有类名的特殊内部类,也叫做匿名内部类。匿名内部类适合创建只需要使用一次的类。创建匿名内部类时须继承一个已有的父类或实现一个接口。由于匿名类本身无名,因此也就不存在构造方法,而且匿名类不能重复使用。

具体可以参考

Anonymous Classes (The Java™ Tutorials > Learning the Java Language > Classes and Objects) (oracle.com)

 

2、定义匿名内部类

本地类是类声明,而匿名类是表达式,这意味着可以在另一个表达式中定义该类。

匿名类本身没有名字,在创建的时候用new语句的一部分来声明。格式如下:

new父类名/接口名{
    //
}

 

例如:

package com.atguigu.java;

class HelloWorldAnonymousClasses {

    interface HelloWorld {
        public void greet();
        public void greetSomeone(String someone);
    }

    public void sayHello() {
        // 局部类实现HelloWorld接口
        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接口
        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();
        spanishGreeting.greet();
    }

    public static void main(String... args) {
        HelloWorldAnonymousClasses myApp = new HelloWorldAnonymousClasses();
        myApp.sayHello();
    }
}

 

3、匿名内部类的语法

如前所述,匿名类是一种表达式。匿名类表达式的语法就像构造器的调用,但代码块中包含类定义。

实现接口的匿名类

public class Test {
    public static void main(String[] args) {
        MyInterface mi = new MyInterface() {
            @Override
            public void say() {
                System.out.println("实现接口 hello");
            }
        };
        mi.say();
    }
}

interface MyInterface{
    void say();
}

 

继承父类的匿名子类

public class Test {
    public static void main(String[] args) {
        // 多态:父类类型的变量指向子类类型的对象,调用方法的时候,是调用子类的实现(子类重写、实现)
        MyClass mc = new MyClass("subclass"){
            public void hello(){
                System.out.println(name+",匿名子类问好");
            }
        };
        mc.hello();
    }
}

class MyClass{
    public String name;

    public MyClass(String name) {
        this.name = name;
    }
    public void hello(){
        System.out.println("hello");
    }
}

 

从上面可以看出,匿名类表达式包括以下内容:

  • 操作符 new

  • 要实现的接口名称或要扩展的类的名称。

  • 包含构造器参数的括号,就像正常的类实例创建表达式一样。注意:当实现接口时,没有构造器,因此使用空的括号,如果是匿名子类,与实例化普通类的语法类似。

  • 一个主体{}。

  • 匿名类的声明是一个表达式,是语句的一部分,以分号结尾。

 

访问作用域内的局部变量、定义和访问匿名内部类成员

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

  • 匿名类可以访问其外部类的成员。

  • 匿名类无法访问其外部类未声明为或有效最终的本地变量。(注意:JDK1.8即使没有用final修饰也可以访问)

  • 与嵌套类一样,匿名内部类定义的类型(如变量)会屏蔽其作用域范围内的其他同名类型(变量)。

匿名内部类对其成员也有与本地类相同的限制:

  • 不能在匿名类中声明静态属性和方法。

  • 匿名类可以具有静态成员,前提是它们是常量。

请注意,您可以在匿名类中声明以下事项:

  • 字段

  • 额外方法(父接口、类中没有的方法)

  • 实例初始化器

  • 内部类

但是不能在匿名类中声明构造器。

 

posted @ 2021-07-29 15:38  r1-12king  阅读(273)  评论(0编辑  收藏  举报