java 匿名内部类 Anonymous Classes
1、简介
匿名类是一个没有类名的特殊内部类,也叫做匿名内部类。匿名内部类适合创建只需要使用一次的类。创建匿名内部类时须继承一个已有的父类或实现一个接口。由于匿名类本身无名,因此也就不存在构造方法,而且匿名类不能重复使用。
具体可以参考
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修饰也可以访问)
-
与嵌套类一样,匿名内部类定义的类型(如变量)会屏蔽其作用域范围内的其他同名类型(变量)。
匿名内部类对其成员也有与本地类相同的限制:
-
不能在匿名类中声明静态属性和方法。
-
匿名类可以具有静态成员,前提是它们是常量。
请注意,您可以在匿名类中声明以下事项:
-
字段
-
额外方法(父接口、类中没有的方法)
-
实例初始化器
-
内部类
但是不能在匿名类中声明构造器。