java 类型转换与编译错误,运行时错误

在特定的情况下,我们可以把子类转换成父类的“实例”,这就是向上转型;相反,我们也可以把父类转换成子类的“实例”,这就是向下转型。向上转型是安全的,向下转型则不然。
假设我们有三个类: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,运行时将会出现错误。


感谢金丝燕大学校长

你可能感兴趣的:(java)