匿名类
和子类有关的匿名类
假如没有显式地声明一个类的子类,而又想用子类创建一个对象,那么该如何实现这一目的呢?Java允许我们直接使用一个类的子类的类体创建一个子类对象,也就是说,创建子类对象时,除了使用父类的构造方法体外还有类体,此类体被认为是一个子类去掉类声明后的类名,称作匿名类。匿名类就是一个子类,由于无名可用,所以不可能用匿名类声明对象,却可以直接用匿名类创建个对象。
假设Bank是类,那么下列代码就是用Bank的一个子类(匿名类) 创建对象。
new Bank(){
匿名类的类体
};
匿名类有如下特点。
(1)匿名类可以继承父类的方法也可以重写父类的方法。
(2)使用匿名类时,必然是在某个类中直接用匿名类创建对象,因此匿名类定是内部类。
(3)匿名类可以访问外嵌类中的成员变量和方法,匿名类的类体中不可以声明static成员变量和static方法。
(4)由于匿名类是一个子类,但没有类名,所以在用匿名类创建对象时,要直接使用父类的构造方法。
尽管匿名类创建的对象没有经过类声明步骤,但匿名对象的引用可以传递给个匹配的参数。
比如,用户程序中有如下方法:
void f(A a){
}
该方法的参数类型是A类,用户希望向方法传递A的子类对象,但系统没有提供符合要求的子类,那么用户在编写代码时就可以考虑使用匿名类。
下面的例子中,抽象类OuputAlphabet有output()方法,而且该类有一个OutputEnglish子类,这个子类重写的output()方法可以输出英文字母表。
例子中的ShowBoard类的showMess(OutputAlphabet show)方法的参数是OutputAlphabet类型的对象,用户在编写程序时,希望使用ShowBoard类的对象调用showMess(OutputAlphabet show)输出英文字母表和希腊字母表,但系统没有提供输出希腊字母表的子类(只提供了输出英文字母表的子类),因此用户在主类的main方法中,向showMess方法的参数传递了一个匿名类的对象,该匿名类的对象负责输出希腊字母表。运行效果如图所示。
abstract class OutputAlphabet {
public abstract void output();
}
class OutputEnglish extends OutputAlphabet{ //输出英文字母的子类
public void output() {
for(char c='a';c<='z';c++) {
System.out.printf("%3c",c);
}
}
}
class ShowBoard{
void showMess(OutputAlphabet show) { //参数show是OutputAlphabet类型的对象
show.output();
}
}
public class Example5.2{
public static void main(String args[]) {
ShowBoard board=new ShowBoard();
board.showMess(new OutputEnglish()); //向参数传递OutputAlphabet的子类OutputEnglish的对象
System.out.println();
board.showMess(new OutputAlphabet() { //向参数传递OutputAlphabet的匿名子类的对象
public void output() {
for(char c='α';c<='ω';c++) //输出希腊字母
System.out.printf("%3c",c);
}
}
); //请注意分号在这里
}
}