class Base
{
}
class Sub extends Base
{
}
class Sub2 extends Base
{
}
class temp
{
public static void main(String argv[])
{
Base b=new Base();
Sub s=(Sub) b;
}
}
{
}
class Sub extends Base
{
}
class Sub2 extends Base
{
}
class temp
{
public static void main(String argv[])
{
Base b=new Base();
Sub s=(Sub) b;
}
}
编译能通过,运行提示的错误是:
Exception in thread "main" java.lang.ClassCastException: Base
at temp.main(temp.java:19)
错在哪?
初步估计是因为子类不能强制转换为父类类型,但是父类可以转换为子类类型,不知道有没有达人来确定一下~~~~
好用啊
在Java中只允许将子类型转换为父类型。象下面的是可以的:
Sub s = new Sub();
Base b = (Base)s;
Base b = new Sub();
Sub s = (Sub)b;
严格意义上说:
子转父可以 父转子不行 好比可以说男人是人 不能说人是男人一样抽象的说 , 表面上存在向下转型, 向上转型的就不谈了.
具体谈谈向下转型,也就是父转子借用falson(弗声)的例子:
Base b = new Sub();......................1
Sub s = (Sub)b;..........................2
编译,运行都没错,表明实例化类型为Sub类型的引用,并成功将该引用赋值给引用变量b,因为该引用变量是Base类型的,也就是说Sub类型(子类型)可以转变为(Base类型)父类型,
但是可不可以把1句改为Sub s = new Base();呢?
编译提示为不兼容的类型,因为父类不能转化为子类.
falson(弗声)的例子1,2句连在一起看,表面上是实现了向下转型,具体看看这2句话给我们的计算机带来了些什么动作:
Base b ====>在栈内存创建引用变量b,用于指向类型为Base的实例或者Base类的子类类型的实例;
new Sub() ====>在堆内存创建一个类型为Sub的实例对象;
中间加个"=" ====>b指向该实例对象,之后所有对实例对象的操作需要靠b来完成;
来看2句,
Sub s ====>在栈内存创建引用变量s,用于指向类型为Sub的实例对象或者Sub类的子类类型的实例对象;
(Sub)b ====>不会强制转化引用变量b的类型为Sub,而只是将其指向的实例类型强制转化为Sub类型,要想成功转换,转换后的类型必须是转换前类型的子类型或同类型.执行这句后,引用变量仍然是Base类型的.
中间加个"=" ====>引用变量s和b同时指向实例Sub;综上,(Sub)b并不是将b的Base类型转化为了Sub类型,即不是父转子,而只是转换了b所指向的实例的类型,如果认为(Sub)b转换的是引用变量的类型,那么就以为是父转子了.总结完毕,肯定有错误的地方,希望大家继续指正批评~~~~~~~~