java中父类强制转换成子类的错觉
2017-04-04 19:12
369 查看
引言:父类引用指向子类对象在java中十分常见,比如:
Object object=new a();//a是一个类名
但是有时候我们看见子类引用指向了父类对象,就是上边的反过来,比如
![](https://img-blog.csdn.net/20170404191738842?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHd1ODM2MDIzMzcz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图片中圈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");
}
}
子类:
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号代码块中为什么正确,转换的过程中虚拟机到底做了什么,我就不知道了,还望高手大神解答。
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号代码块中为什么正确,转换的过程中虚拟机到底做了什么,我就不知道了,还望高手大神解答。
相关文章推荐
- Java中父类强制转换成子类的原则
- Java中父类强制转换成子类的原则
- java搜索 里 可以把一个父类强制转换成一个子类 不能把一个子类强制转换成一个父类? 对吗?
- Java中父类强制转换为子类的可能
- Java中父类强制转换为子类的可能
- java 父类强制转换为子类
- Java中父类强制转换成子类的原则
- C++父类强制转换为子类用法
- Java子类与父类的转换
- Java 父类与子类 类型转换
- java中父类与子类的转换问题
- Java中父类和子类的类型转换解惑
- java 用户自定义的父类转换成子类的方法
- JAVA父类对象与子类对象-造型转换
- C#父类强制转换成子类,子类隐式转换成父类
- C#中 父类与子类相互强制转换之实验(转帖)
- C#中 父类与子类相互强制转换之实验
- C#中 父类与子类相互强制转换之实验
- Java子类强制转父类类型不会变
- JAVA中子类与父类相互转换