前面我在总结内部类时,没有总结匿名内部类。原因是匿名内部类的使用与抽象类和接口是结合在一起的。在总结完了抽象类和接口之后,再来总结匿名内部类比较恰当。
再对接口说两句。接口不是类,它只是功能的描述。我们知道,Java中不能实现多重继承,一个子类只能有一个父类。如果子类想实现一些父类所没有的功能,就可以使用接口来实现(implement)。格式为:
class A extends B implements C;
extends 在implements前面,不可以颠倒。
接口不是类,它是没有构造方法的。接口的功能的实现要依靠类的实现。
比如,可以创建一个类的对象,然后用接口类型的引用变量指向它。然后通过用这个接口类型的引用变量,来引用对象中实现了的抽象方法。
接口类型 接口名 = new 类名();
接口名.接口方法(); //此方法已被类具体实现
下面回到匿名内部类,我的理解是这样:比如家里来了很多客人,需要有很多凳子坐一下。客人就来一次,临时去买很多凳子就不划算。所以,就可以去借凳子用。借一次,用完就还了,这样,成本比较低。
匿名内部类也是这样,它是类,但是没有名字。因为只用一次,没必要命名。匿名内部类有2个应用场合:
1。在父类(包括抽象类和一般类)中使用匿名内部类
2。在接口中使用匿名内部类
匿名内部类的使用语法如下:
new 类型名(构造方法参数){ //这里的类型可以是类,或者接口,对于接口就没有参数
implement some methods; //实现抽象方法,必须全部实现抽象方法,否则会出错
}
下面用一个例子来说明:
abstract class test1{ //抽象类test1
abstract void method1(); //抽象类的抽象方法method1,必须在匿名内部类中实现,否则会出错
// abstract void method11(); //抽象类的抽象方法method11,必须在匿名内部类中实现,否则会出错
void method111(){ //抽象类的一般方法method111,不必在匿名内部类中实现
}
}
interface test2{ //接口test2
abstract void method2(); //接口的抽象方法method2
}
class test3{ //普通类test3
void method3(){ //普通类的普通方法method3
}
}
public class anonymous{
public static void main(String[] args){
test1 t1 = new test1(){ //根据抽象类test1创建匿名内部类的对象t1
void method1(){ //实现抽象方法,这里必须全部实现test1的抽象方法,否则会出错
System.out.println("implement method1");
}
};
t1.method1(); //使用匿名内部类的对象的方法
new test1(){ //创建匿名内部类的对象,但不使用引用型变量指向它,只使用一次它的方法
void method1(){
System.out.println("implement method1 again");
}
}.method1();
new test3(){ //根据父类test3创建匿名内部类对象,test3并不是抽象类
void method3(){
System.out.println("Hello!");
}
}.method3(); //使用父类test3的方法method3
test2 t2 = new test2(){ //根据接口test2创建匿名内部类对象t2
public void method2(){
System.out.println("implement method2 ");
}
};
t2.method2(); //使用匿名内部类对象t2的方法method2
new test2(){ //根据接口test2创建匿名内部类对象,但并不使用变量指向它。
public void method2(){
System.out.println("implement method2 again ");
}
}.method2(); //直接在对象中使用它的方法method2
}
}
在理解匿名内部类的时候,要注意:
1。匿名内部类的对象是使用new语句来创建的,但是抽象类和接口并不能new。这里new的是(全部实现了抽象方法的)匿名内部类,并不是抽象类,或者接口。
2。在new完匿名内部类后,系统得到的是一个对象,那么就自然可以用这个对象来引用创建它的匿名内部类的方法。这里要时时分清蓝图和房子的区别。new出的是一个房子,匿名内部类是蓝图,抽象类和接口是蓝图的蓝图。房子 new出来以后,如果需要开窗,就调用蓝图中已经implement了的开窗这个方法。要在写代码,读代码的时候,把空间感建立起来。