匿名内部类:一种特殊的局部内部类,它是通过匿名类实现接口
IA被定义为接口:
IA = new IA(){};
匿名内部类的特点:
1.一个类用于继承其他类或者实现接口,并不需要增加额外的方法,只是对继承方法的覆盖。
2.只是为了获得一个对象实例,不需要知道其实际类型
3.类名没有意义,也就不需要使用到。
匿名内部类也就是没有名字的内部类
正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写
但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口
实例1:不使用匿名内部类来实现抽象方法
abstract class Person {//抽象类
public abstract void say();
}
class Child extends Person {//继承抽象类
public void say() {
System.out.println("hello!");
}
}
public class Demo {
public static void main(String[] args) {
Person p = new Child();
p.say();
}
}
运行结果:hello
可以看到,我们用Child继承了Person类,然后实现了Child的一个实例,将其向上转型为Person类的引用
但是,如果此处的Child类只使用一次,这个时候就引入了匿名内部类。
实例2:匿名内部类的基本实现
abstract class Person {
public abstract void say();
}
public class Demo {
public static void main(String[] args) {
Person p = new Person() {
public void say() {
System.out.println("hello!");
}
};
p.say();
}
}
运行结果:hello!
直接将抽象类Person中的方法在大括号中实现了,这样便可以省略一个类,并且匿名内部类还能用于接口上。
实例3:在接口上使用匿名内部类
interface Person {
public void say();
}
public class Demo {
public static void main(String[] args) {
Person p = new Person() {
public void say() {
System.out.println("hello!");
}
};
p.say();
}
}
运行结果:hello!
由上面的例子可以看出,只要一个类是抽象的或是一个接口,那么其子类中的方法都可以使用匿名内部类来实现,最常用的情况就是在多线程的实现上,因为要实现多线程必须继承Thread类或是继承Runnable接口。
实例4:Thread类的匿名内部类实现
public class Demo {
public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.print(i + " ");
}
}
};
t.start();
}
}
运行结果:1 2 3 4 5
实例5:Runnable接口的匿名内部类实现
public class Demo {
public static void main(String[] args) {
Runnable r = new Runnable() {
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.print(i + " ");
}
}
};
Thread t = new Thread(r);
t.start();
}
}
运行结果:1 2 3 4 5
注意:
在使用匿名内部类时,要记住以下几个原则:
- 匿名内部类不能有构造方法。
- 匿名内部类不能定义任何静态成员、方法和类。
- 匿名内部类不能是public,protected,private,static。
- 只能创建匿名内部类的一个实例。
- 一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
- 因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。
- 静态内部类只能访问外部类的静态变量或静态方法。(final修饰的)
匿名类和内部类中的this :
当在匿名类中用this时,这个this则指的是匿名类或内部类本身。这时如果我们要使用外部类的方法和变量的话,则应该加上外部类的类名。
注:一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类,没有类名,根据多态,我们使用其父类名。
因它是局部内部类,那么局部内部类的所有限制都对其生效。
匿名内部类是唯一一种无构造器方法类。大部分匿名内部类是用于接口回调用的。 * 匿名内部类在编译的时候由系统自动起名NonameInnerClass$1.class。
如果一个对象编译时的类型是接口,那么其运行的类型为实现这个接口的类。
因匿名内部类无构造方法,所以其使用范围非常有限。
当需要多个对象时使用局部内部类,因此局部内部类的应用相对比较多。
匿名内部类中不能定义构造方法。