引言:父类引用指向子类对象在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号代码块中为什么正确,转换的过程中虚拟机到底做了什么,我就不知道了,还望高手大神解答。