java 类型转换与编译错误,运行时错误
2014-07-10 20:21
363 查看
在特定的情况下,我们可以把子类转换成父类的“实例”,这就是向上转型;相反,我们也可以把父类转换成子类的“实例”,这就是向下转型。向上转型是安全的,向下转型则不然。
假设我们有三个类:bird,parrot,swallow,后两个类继承了bird类。
向上转型
我们使用Bird b = p这个语句将p转型为bird的一个实例。然后,当调用b.fly()时,实际上调用的仍然是bird的fly()方法;但是当调用b.eat时,实际上调用的parrot的方法eat方法,而不是bird的eat方法。另外,当p转型为bird后,由于bird没有say方法,那么b.say方法不可用。
向下转型
混合转型
如果我们直接使用s = (Swallow)p进行转型,那么在编译时就会产生错误。但是如果先把一个parrot的实例转换成bird,然后再把bird转换成swallow,运行时将会出现错误。
总结:
关于强制类型转换, 一共有两种类型的强制类型转换:
A) 向上类型转换(upcast):比如说将Cat类型转换为animal类型,即将子类型转换为父类型。对于向上类型转换,不需要显式指定。
B) 向下类型转换(downcast):比如将animal类型转换为cat类型。即将父类型转换为子类型,对于向下类型转换,必须要显式指定(必须要使用强制类型转换)。不是什么父类型都可以向下转换的,要看这个父类型变量具体指向的是什么对象。
为什么要使用向下类型转换?为了使用子类中特有的方法和属性,按照继承,父类中有的子类中一定有,子类中可以增加新的和修改原有的,而如果使用父类型指向一个子类型对象,就不能使用子类中的新增方法等。
public class PolyTest3
{
publicstatic void main(String[] args)
{
/*
Animal animal = new Cat();
Animal animal2 = new Animal();
animal2 =animal;
//animal和animal2都是Animal类型变量,同种变量类型可以相互赋值
//animal2由原来的指向Animal对象改为指向Cat对象
animal2.run();
//打印结果为cat is run
*/
/*
Animal animal = new Cat();
Animal animal2 = new Animal();
animal =animal2;
//animal和animal2都是Animal类型变量,同种变量类型可以相互赋值
//animal由原来的指向Cat对象改为指向Animal对象
animal.run();
//打印结果为animal is run
*/
Cat cat = new Cat();
Animal animal = cat;
//animal和cat是不同类型的类型变量,将Cat类型变量赋值给Animal类型变量
//animal指向Cat对象,父类型变量指向子类型对象
animal.run();
//打印结果为子类型方法结果:cat is run
/*
Animal animal = new Animal();
Cat cat = (Cat)animal;
//编译通过,运行错误,
*/
//向上类型转换
Cat cat =new Cat();
Animal animal = (Animal)cat;
//这里(Animal)cat是向上类型转换,可以不显示转换直接写cat
animal.run();
//向下类型转换
Animal a =new Cat();
//Cat cat =a;这样写不行,这样写就是说父类就是子类
Cat c =(Cat)a;
c.run();
}
}
class Animal
{
publicvoid run()
{
System.out.println("animal is run");
}
}
class dog extends Animal
{
publicvoid run()
{
System.out.println("dog is run");
}
}
class Cat extends Animal
{
publicvoid run()
{
System.out.println("cat is run");
}
}
参考:
http://blog.csdn.net/kaoa000/article/details/8308700
http://blog.csdn.net/zhu_apollo/article/details/1903374
http://blog.csdn.net/shanghui815/article/details/6088588
http://www.java3z.com/cwbwebhome/article/article8/81157.html?id=2664
http://www.cnblogs.com/fickleness/archive/2013/06/21/3149011.html
感谢金丝燕大学校长
假设我们有三个类:bird,parrot,swallow,后两个类继承了bird类。
向上转型
class Bird { public void fly() { System.out.println("Bird.fly()"); } public void eat() { System.out.println("Bird.eat()"); } } class Parrot extends Bird{ public void eat() { System.out.println("Parrot.eat()"); } public void say() { System.out.println("Parrot.say()"); } } class Swallow extends Bird{ public void eat() { System.out.println("Swallow.eat()"); } public void sleep() { System.out.println("Swallow.sleep()"); } } public class Main{ public static void main(String args[]) { Main main = new Main(); main.upcast(); } public void upcast() { Parrot p = new Parrot(); p.fly(); p.say(); p.eat(); Bird b = p; b.fly(); b.eat(); //b.say(); 转型成Bird后,say方法不可见 } } 结果为: Bird.fly() Parrot.say() Parrot.eat() Bird.fly() Parrot.eat()Bird类有一个fly方法,子类parrot和swallow都可以使用它;bird有一个eat方法,子类parrot和swallow覆盖了整个方法;子类parrot增加了一个say方法,子类swallow增加了一个sleep方法。
我们使用Bird b = p这个语句将p转型为bird的一个实例。然后,当调用b.fly()时,实际上调用的仍然是bird的fly()方法;但是当调用b.eat时,实际上调用的parrot的方法eat方法,而不是bird的eat方法。另外,当p转型为bird后,由于bird没有say方法,那么b.say方法不可用。
向下转型
public class Main2 { public static void main(String[] args) { Main2 main = new Main2(); main.downcast(); main.downcastError(); } public void downcast() { System.out.println("如果这样向下转型,将不会产生错误"); Bird b = new Parrot(); Parrot p = (Parrot)b; p.fly(); } public void downcastError() { System.out.println("如果这样向下转型,将会产生错误"); Bird b = new Bird(); Parrot p = (Parrot)b; p.fly(); } }第一种转型方法之所以能够顺利进行,是因为bird b本来就是一个parrot实例,我们把它转回去,当然不会出错。
混合转型
public class Main3 { public static void main(String[] args) { Main3 main = new Main3(); main.multcast(); } public void multcast() { Bird b; Parrot p = new Parrot(); Swallow s; //s = (Swallow)p;编译错误 b = (Bird)p; b.eat(); s = (Swallow)b;//编译顺利,运行错误0 s.eat(); } }
如果我们直接使用s = (Swallow)p进行转型,那么在编译时就会产生错误。但是如果先把一个parrot的实例转换成bird,然后再把bird转换成swallow,运行时将会出现错误。
总结:
关于强制类型转换, 一共有两种类型的强制类型转换:
A) 向上类型转换(upcast):比如说将Cat类型转换为animal类型,即将子类型转换为父类型。对于向上类型转换,不需要显式指定。
B) 向下类型转换(downcast):比如将animal类型转换为cat类型。即将父类型转换为子类型,对于向下类型转换,必须要显式指定(必须要使用强制类型转换)。不是什么父类型都可以向下转换的,要看这个父类型变量具体指向的是什么对象。
为什么要使用向下类型转换?为了使用子类中特有的方法和属性,按照继承,父类中有的子类中一定有,子类中可以增加新的和修改原有的,而如果使用父类型指向一个子类型对象,就不能使用子类中的新增方法等。
public class PolyTest3
{
publicstatic void main(String[] args)
{
/*
Animal animal = new Cat();
Animal animal2 = new Animal();
animal2 =animal;
//animal和animal2都是Animal类型变量,同种变量类型可以相互赋值
//animal2由原来的指向Animal对象改为指向Cat对象
animal2.run();
//打印结果为cat is run
*/
/*
Animal animal = new Cat();
Animal animal2 = new Animal();
animal =animal2;
//animal和animal2都是Animal类型变量,同种变量类型可以相互赋值
//animal由原来的指向Cat对象改为指向Animal对象
animal.run();
//打印结果为animal is run
*/
Cat cat = new Cat();
Animal animal = cat;
//animal和cat是不同类型的类型变量,将Cat类型变量赋值给Animal类型变量
//animal指向Cat对象,父类型变量指向子类型对象
animal.run();
//打印结果为子类型方法结果:cat is run
/*
Animal animal = new Animal();
Cat cat = (Cat)animal;
//编译通过,运行错误,
*/
//向上类型转换
Cat cat =new Cat();
Animal animal = (Animal)cat;
//这里(Animal)cat是向上类型转换,可以不显示转换直接写cat
animal.run();
//向下类型转换
Animal a =new Cat();
//Cat cat =a;这样写不行,这样写就是说父类就是子类
Cat c =(Cat)a;
c.run();
}
}
class Animal
{
publicvoid run()
{
System.out.println("animal is run");
}
}
class dog extends Animal
{
publicvoid run()
{
System.out.println("dog is run");
}
}
class Cat extends Animal
{
publicvoid run()
{
System.out.println("cat is run");
}
}
参考:
http://blog.csdn.net/kaoa000/article/details/8308700
http://blog.csdn.net/zhu_apollo/article/details/1903374
http://blog.csdn.net/shanghui815/article/details/6088588
http://www.java3z.com/cwbwebhome/article/article8/81157.html?id=2664
http://www.cnblogs.com/fickleness/archive/2013/06/21/3149011.html
感谢金丝燕大学校长
相关文章推荐
- Java数组类型强转编译无错,运行报转换错误
- 类型转换中的编译错误与运行错误
- Java 编译,运行错误之 java.lang.UnsupportedClassVersionError: Bad version n umber in .class file
- java学习之编译时类型和运行时类型
- 语法错误javac(编译),逻辑错误java(运行)
- java新手,什么情况下发生编译错误,什么情况下发生运行错误!
- 关于 Java源文件带有package的普通程序和Applet编译和运行时错误的处理方法
- java学习笔记11——编译时类型和运行时类型
- java类型转换错误信息incompatible with
- java学习之编译时类型和运行时类型
- Dos 下编译java文件引用到多个第三方jar时必须逐个指定到具体的jar,否则报找不到类型错误
- 类型转换错误java.math.BigDecimal cannot be cast to java.lang.String
- Java编译时类型与运行时类型以及重载和覆盖方法选择
- JAVA 编译运行中错误的解决办法
- Flex与Java使用BlazeDS交互时类型转换错误
- Java 编译,运行错误之 java.lang.UnsupportedClassVersionError: Bad version n umber in .class file
- Java学习之编译时类型和运行时类型
- java之编译时类型(前期绑定)和运行时类型 (后期绑定、动态绑定、运行时绑定)
- 奇怪的hibernate 的类型转换错误: java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang
- 一个VC编译错误引发的对显示类型转换的思考(static_cast、dynamic_cast和const_cast)