[Java] Java 向上与向下类型转换

[复制链接]

51

主题

56

帖子

283

积分

版主

代码控

Rank: 7Rank: 7Rank: 7

积分
283

突出贡献优秀版主荣誉管理

QQ
317 0 joy 发表于 2016-12-30 22:27:18

  通俗理解向上转型:就是子类转型成父类。
  1. class A { }
  2. class B extends A { }
  3. A a = new B();
复制代码

  这个就是向上转型。

  向上转型可以像下面这条语句这么简单:
  1. Shape s = new Circle();
复制代码


  这里,创建一个Circle对象,并把得到的引用立即赋值给s,这样做看似错误(将一种类型赋值给另一种类型),但实际上没有问题。
  因为通过继承,Circle就是一种Shape(子类是父类,就如男人是人一样)。编译器认可这条语句,也就不会产生错误信息。

  假设你调用了一个父类方法(它已经在子类中被覆盖)
  1. s.draw();
复制代码

  你可能认为调用的是Shape 的draw()方法,因为这毕竟是一个Shape引用,但此时s真正指向的是Circle对象,由于后期绑定(多态),编译器还是正确调用了Circle的draw()方法。


总结:
  1.通过父类型引用指向子类型对象来实现动态调用
B b = new B();
A a = b;  //A为基类,B是继承A的子类
a.play();  //play()在A,B中均有定义,即子类重写(覆写)了该方法

  分析:
  # 为什么父类型的引用可以指向子类型的对象?
  自动实现向上转型。通过A a = b;语句,编译器自动将子类对象向上移动,成为A类型

  # a.play()将执行子类还是父类中定义的方法?
  子类的。在运行时期,将根据a这个引用所指向的实际对象来获取相应的方法,这也是多态性。一个父类的引用,指向不同的子类对象,执行该方法时,将表现出不同的行为。


  2.不能将子类引用指向父类对象
  1. A a = new A();
  2. B b = a; //这样是不行的,对比前面,可以知道父类不是子类(如同人不是男人)
复制代码

  在java中,向上转型是自动进行的,但是向下转型却不是,需要我们强制进行类型转换。如:
  1. B b = new B();
  2. A a = b;
  3. B bb = (B)a;  //进行强制类型转换,也就是向下转型
复制代码


  3.记住一个简单而又复杂的规则:
  一个类型引用只能引用引用类型自身含有的方法和变量,你可能说这个规则不对,因为父类引用指向子类对象时,最后执行的是子类的方法。其实这并不矛盾,那是因为采用了后期绑定(多态),运行时编译器又根据引用指向的实际类型去调用了子类的方法,而假若子类的这个方法在父类中并没有定义,则编译会出错。

  分析:
  当你使用父类引用指向子类对象的时候,其实jvm(java virtual machine)已经使用了编译器产生的类型信息调整转换了。这里你可以这样理解,相当于把不是父类中含有的方法从虚拟函数表中设置为不可见的,注意有可能虚拟函数表中有些函数地址由于在子类中已经被改写了,所以对象虚拟函数表中虚拟函数项目地址已经被设置为子类中完成的方法体的地址了。

夜深人静之时,头发斑白的老程序员会蜷缩在床上,欣赏一段精彩的子程序,或者苦思冥想一个绝妙的宏结构;而那些年少轻狂的程序员,则可能正在通过终端与别人聊得不亦乐乎。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

本专栏主要提供Java相关技术的学习交流。望大家积极踊跃发言,共建一个良好的学习环境!
  • 今日
    0
  • 主题
    365

推荐阅读

精选帖子

Archiver|手机版|小黑屋| 极客社区 ( 京ICP备14042200号-2 )

Powered by 张董丶 X3.2 © 2016-2026

返回顶部 返回列表