引言:父类引用指向子类对象在java中十分常见,比如:
Object object=new a();//a是一个类名
但是有时候我们看见子类引用指向了父类对象,就是上边的反过来,比如
图片中圈1标识的代码,反正就是怎么看都别扭,但是却一点问题没有。(图片是疯狂android讲义的截图,379页,讲述activity和service传递消息的那个章节。IBender是个接口,BinderService.MyBinder是实现该接口的类的一个子类)对此,所以我做了实验:
父类:
package testjar; public class a { public a() { // TODO Auto-generated constructor stub //System.out.println("a构造方法"); } public a(int i) { //System.out.println(i+""); } public void a_fun(){ System.out.println("a->a_fun"); } } 子类: package testjar; public class b extends a { public b() { // TODO Auto-generated constructor stub super(); //System.out.println("b 构造方法"); } @Override public void a_fun() { // TODO Auto-generated method stub super.a_fun(); System.out.println("b->a_fun"); } } main:package testjar; public class e { public e() { // TODO Auto-generated constructor stub } public static void main(String[] args) { // TODO Auto-generated method stub a aa=new a();//注意这里 b bb=(b)aa;//注意这里 bb.a_fun(); } } 运行后,就抛出了异常: Exception in thread "main" java.lang.ClassCastException: testjar.a cannot be cast to testjar.b at testjar.e.main(e.java:12)
很明显,转换失败,也算是意料之中,根本不符合逻辑,但是上边图片的android代码为什么没有问题
我们只要修改一下代码:
package testjar; public class e { public e() { // TODO Auto-generated constructor stub } public static void main(String[] args) { // TODO Auto-generated method stub a aa=new b();//注意这里 b bb=(b)aa;//注意这里 bb.a_fun(); } } 注意我注释的注意这里的地方,就把a改成了b,就一切正常了。打印结果:
a->a_fun b->a_fun
看到这里,我想明白了,IBender只是个参数,android系统在调用onServiceConnected回调方法的时候就已经实现了service的指向对象,只不过肯定不是IBender接口实现后的对象,而是子对象,只是参数类型写成了IBender,(心中万马奔腾)。
我们回到java角度上来,
总结一下:
1父对象=new 父类();
2子对象=new 子类();
3父对象=new 子类();
4{
父对象=new 子类();
子对象=(子类)父对象;
}
上述四个都是正确的。
/*************************************************************************/
但是这个就不对了:
{
父对象=new 父对象();
子对象=(子类)父对象;
}
就会抛出刚刚说过的异常(注意两个红色部分)。所以我认为,4号代码块很容易迷惑我这样的新手,我叫他错觉(这个java是假的)。
不过到底为什么,在4号代码块中为什么正确,转换的过程中虚拟机到底做了什么,我就不知道了,还望高手大神解答。
