在上一篇文章中,已经系统的阐述了向上强制类型转换的原理。近日,苦思向下类型绑定,终于有了自己的理解,拿出来与大家分享,希望大家对我的理解指点一二。
import java.util.*;
import static java.lang.System.out;class Useful{
  public void f(){out.println("Useful.f()");}
  public void g(){out.println("Useful.g()");}
}class MoreUseful extends Useful{
  public void f(){out.println("MoreUseful.f()");}
  public void g(){out.println("MoreUseful.g()");}
  public void u(){out.println("MoreUseful.u()");}
  public void v(){out.println("MoreUseful.v()");}
  public void w(){out.println("MoreUseful.w()");}
}public class Rtti{
   public static void main(String [] args){
     Useful s = new MoreUseful(); 
     s.f();
     s.g();
---------------------------------------------------------------------------------------------------------------------
    s.u();
这个操作是不会被jvm接受的。在向上类型转换中能够访问的方法列表源自句柄,也就是对象的声明类型(Useful),如果在子类中覆盖了父类中的方法,那么在程序运行时绑定时运行的是对象的实际类型中的方法。我们看到u()方法并没有在父类中进行声明,而是子类特有的。
__________________ok,此时如果想直接访问子类中特有的方法我们应该怎么做呢?-------------------------
((MoreUseful)s).u();    //or MoreUseful m = (MoreUseful)s; m.u();
这就是常说的向下类型转换,在这里我认为最应该掌握的一句话就是“强制类型转换是发生在引用上的”,此时我们的句柄变成了MoreUseful,注意,此时程序运行时jvm得到的方法列表源自带有u();的MoreUseful。
-------------------------------------------------------------------------------------------------------------------------
我在想到这时突然产生了一个疑问(当然对于java经验丰富的老鸟就当看个笑话啦)
我的疑问是为什么还要强转呢,直接MoreUseful m1 = new MoreUseful();不就一切都搞定了吗?没错。
out.println(s.toString());      //注意我引入的包,1.5中是可以去掉大小写混在一起的System
out.println(m.toString());
out.println(m1.toString());
s、m只是引用上的转换,m1是新建了一个对象。这是我觉得实际中有用的地方,请大家再补充一下向下强制类型转换在实际应用中还有什么其它的作用。

解决方案 »

  1.   

    我的疑问是为什么还要强转呢,直接MoreUseful   m1   =   new   MoreUseful();不就一切都搞定了吗?没错。
    ////////////////////////////////////////////////////////////////////////////////////////////////
    如果你创建了不止一个这个类的子类的时候你就会知道为什么要用声明父类却指向子类对象了!这和接口的概念是一样的,一个接口可以有任意多个实现,但是每个实现的方式和提供的功能可以都不一样.
    如果你在哪个地方想用这个接口时,你可以直接传入接口的引用,而不是传入它的某个实现类的引用,这样就可以用接口引用来传入不同的实现类实例,来实现不同的功能了!