02. Java基础之向上和向下转型

       向上转型会丢失子类多余父类的那部分方法;向下转型分为两种,一种是通过子类b向上转换为父类a,然后又由a向下转换为子类,这种完全可以通过编译和运行;而另外一种是先通过父类创建父类对象,然后由父类向下转换为子类,这种编译正确,但是会抛出运行时异常:java.lang.ClassCastException.

如下是一个综合例子说明:

1 package com.test.a;
2 
3 public class Base {
4     public void f()
5     {
6         System.out.println("Base.f");
7     }
8 
9 }
View Code
 1 package com.test.a;
 2 
 3 public class Sub extends Base{
 4     public void f()
 5     {
 6         System.out.println("Sub.f");
 7     }
 8     
 9     public void f2()
10     {
11         System.out.println("Sub.f2");
12     }
13 
14 }
View Code
 1 package com.test.a;
 2 
 3 public class Test {
 4     public static void main(String args[]) {
 5         //******向上转型****************
 6         Base base1=new Sub();
 7         base1.f();//print sub.f
 8 //        base1.f2();//compile error,因为sub比base多的那些方法在向上转型的过程中将要丢失
 9         
10         //********向下转型1********
11         Sub sub1=(Sub)base1;
12         sub1.f();//print sub.f
13         sub1.f2();//print sub.f2
14         
15         //********向下转型2*********
16         Base base2=new Base();
17         Sub sub2=(Sub)base2;//ClassCastException
18         sub2.f();//ClassCastException
19         sub2.f2();//ClassCastException        
20     }
21 
22 }
View Code

       为什么两种向下转型会有如此差异?这是因为前者base1指向了子类Sub的对象,所以子类Sub的实例对象当然也可以指向base1。而base2是一个父类对象,子类对象sub2不能指向父类对象base2。

       那如何避免运行异常java.lang.ClassCastException,可以采用instanceof来避免:

 1 package com.test.a;
 2 
 3 public class Test {
 4     public static void main(String args[]) {
 5         //******向上转型****************
 6         Base base1=new Sub();
 7         base1.f();//print sub.f
 8 //        base1.f2();//compile error,因为sub比base多的那些方法在向上转型的过程中将要丢失
 9         
10         //********向下转型1********
11         Sub sub1=(Sub)base1;
12         sub1.f();//print sub.f
13         sub1.f2();//print sub.f2
14         
15         //********向下转型2*********
16         Base base2=new Base();
17         if(base2 instanceof Sub)
18         {
19             Sub sub2=(Sub)base2;//ClassCastException
20             sub2.f();//ClassCastException
21             sub2.f2();//ClassCastException    
22         }
23             
24     }
25 
26 }
View Code

      向上转型的好处,比如可以在方法参数中只传入父类的引用,而具体是哪个子类还是父类对象交给编译器自己决定----后期绑定,减小代码的复杂啦。父类可以提供好更多可能的接口供子类使用;向下转型的好处,比如泛型机制的引入,这样就可以避免stiring和integer类型都加入了list,最终类型转换时报错。

    

原文地址:https://www.cnblogs.com/Hermioner/p/9487179.html