java中各种类的跳转例题分析
在学习java的继承的过程中遇到这样的一个分析类题目,比较有意思,在这里做出简要分析:
//请写出以下程序运行结果:
package test;
public class Test {
public static void main(String[] args) {
Test t = new Test();
t.show(new Car(){
public void run(){
System.out.println("test run");
}
});
}
public void show(Car c){
c.run();
c.show();
}}
abstract class Car{
public void run(){
System.out.println("car run");
}
public void show(){
System.out.println(getClass().getName());
}}
那么,我们可以通过断点的分析:
首先。我们从main函数进入,发现他创建了Test类的一个对象t;
我们在test类中并没有寻找到Test类的构造函数,所以应该是系统默认的构造器,不进行任何的行为;
之后,我们注意一下这一步,首先是t.show()方法,在Test的类中有这么一个方法,不过我们看到show方法是需要传入一个car类的对象,所以他new了一个car对象,离奇的是car对象后面接着一对大括号。
注意到:这里有一个匿名类,用来一次性使用的创建car对象。这样抽象类car才能被以匿名类中的内容实例化。这样,我们就完成了对car类的实例化,得到了一个car类的对象。
接着,我们以那个新new的对象作为参数,调用了Test类中的show方法。
而show方法的第一条语句是c.show();注意到我们是通过匿名类创建的对象,而我们是通过匿名类中的重新写的run()方法,所以他又跳回了第六行,输出“test run”;
好的,接下来我们又回到了show方法中,继续调用c.show(),这时,我们回头看匿名类,它里面竟然没有show的方法。。。所以他就只能调用car类的show()方法。
注意到了右侧返回的getName()是”test.Test$1”,好吧,test是包名,Test是类名,可以理解!
但是$1就使得不少同学迷惑了。
好的,我们这次打开文件管理系统,找到我们编译的文件所在,发现.java编译后多出了Test$1.class的文件,这个.class是怎么来的呢?对了是匿名类!这里的Test$1这个类名是编译器给它的名字(匿名类没有名字,但是java编译器要给他起个名,才好分辨)而命名的格式就是第一个Test类下面的匿名类的话就叫$1,第二个就是$2。
这样就可以了,程序就结束了!主要涉及了匿名成员类。大家有兴趣(最好可以了解一下)