[Java]"向上转型"(Upcasting)的用法和知识点总结





<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>

  •  向上转型(Upcasting)
    "为新的类提供方法"并不是继承技术中最重要的一个方面. 其最重要的方面是它被用来表现新类和基类之间的关系. 这种关系可以用 "新类是先有类(基类)的一种类型" 这句话来加以概括. 就是说,导出类是基类的扩展,是一基类为基础的,那么它必然首先是一个基类.

    这个描述并非只是一种华丽的用以解释继承的方式,而是直接由语言所支撑的特性.例如,假设有一个被称为Instrument用来代表乐器的基类和一个称为Wind的导出类.由于继承意味着基类中所有的方法在导出类中同样有效(或者你可以理解为导出类根本就包含一个基类的对象),所以你能够向基类发送的的所有信息同样可也向导出类发送. 如果Instrument类具有一个play()方法,那么Wind乐器将同样具备. 这意味着我们可以确切的说Wind对象是一种类型的Instrument. 下边的这个例子说明了编译器是怎样支持这一概念的:
  1. import java.util.*;

  2. class Instrument {                         //声明基类Instrument
  3.     public void play() {}              //它有一个公开play方法
  4.     static void tune (Instrument i) {  //它还有一个隶属于类的静态方
  5.         // ...                     //法,并且需要传入一个Instrume
  6.         i.play();                  //nt类型的对象,并且执行play
  7.     }
  8. }

  9. public class Wind extends Instrument {     //声明继承于I的导出类Wind
  10.     public static void main(String[] args) {   //Wind的main方法
  11.         Wind flute = new Wind();           //构建一个Wind对象
  12.         Instrument.tune(flute);      //调用Instrument类的tune方
  13.     }                                 //法,并且传入了对象flute
  14. }
   大家看,在Instrument类的tune方法定义中,要求传入一个Instrument类型的对象,并执行其play方法.而Wind的main方法中调用tune方法时传入的是Wind类型的对象flute.   在没有了解向上转型之前,或许会认为编译器会报错(类型不兼容),实际上这就是向上转型,这样做是被允许的.

   首先,对象flute是Wind类型的,而Wind类继承了Instrument,这样一来对象flute就同时具有了基类Instrument和导出类Wind的所有成员数据和成员方法(当然就具有了tune方法),那么套用上边一段话,对象flute是Wind类型的同时它首先是一个Instrument类型的,既然是Instrument类型的,理所当然的就可以调用tune方法了.

同样可以这样理解: 这么做是将对象flute看作是Instrument类型的(因为他继承于Instrument)!!!
这时在tune方法的眼里,flute只是一个Instrument对象,即tune方法只能看到flute的基类部分.


Thinking In Java中的原版解释:

     " 在此例中,tune()方法可以接受Instrument引用,这是在是太有趣了 但在Wind.main中,tune()方法是通过给它一个Wind引用而被调用的. 鉴于Java对类型的检查十分严格,接受一种类型的方法同样可以接受另外一种类型就会显得很奇怪,除非你能认识到Wind对象同样是一种Instrument对象,而且不存在任何方法是tune()可以通过Instrument来调用,同时不存在于Wind之中的. 在tune()中,程序代码可以对Instrument和他所有的导出类起作用,这种将Wind引用转换为Instrument引用的动作,就称之为"向上转型(Upcasting)".  "


  • 为什么要使用"向上转型"?
    该术语的使用有其历史渊源,并且以传统的类继承图的绘制方法为基础:将根(基类)置于页面的顶端,然后逐渐向下.这样一来. Wind.java的继承图就是:

                    Java的继承示意图

   由导出类转型成基类,在继承图上是向上移动的,因此一般称为"向上转型". 由于向上转型是从一个较专用类型向较通用类型转,所以总是很安全的. 就是说,导出类是基类的一个超集(superset). 他可能比基类含有更多的方法,但它必须至少具备基类中所含有的方法,在向上转型的过程中,对于类接口唯一可能发生的事情是丢失方法,而不是获取它们.这就是为什么编译器在"未曾明确表示转型"或"未曾制定特殊标记"的情况下,仍然允许向上转型的原因.

  • 再说组合与继承
   在面向对象编程中,生成和使用程序代码最有可能采用的方法就是直接将数据和方法包装进一个类中,并使用该类的对象.你可以运用组合技术使用先有类来开发新的类.而继承技术其实不太常用. 因此,你应当慎用这一技术,其使用场合仅限于你确信使用该技术确实有效的情况下.   一个用以判断你到底是使用组合还是使用继承的最清晰的方法,就是问一问你自己是否需要从新类向基类向上转型. 如果你必须向上转型,则继承是必要的.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值