【Keywords】:向上转型 向下转型 动态绑定[1] 静态绑定
【Abstract】:Java调用对象方法时,一般采用运行时绑定机制。[1]
         在程序运行时,采用动态绑定意味着:虚拟机将调用对象实际类型所限定的方法。
         向上转型要点:
           1.定义父类对象指向子类对象。
           2.理解动态绑定。
           3.转型后的父类实例仅可以调用子类继承父类的方法和属性;
           4.转型后的父类实例优先调用子类继承的方法,其次优先调用父类固有方法。                  
         向下转型要点:
           1.向下转型建立在向上转型的基础上[否则:转型不安全]
           2.向下转型时必须进行强制转换。
           3.父类对象(即被转型实例)强制转换类型必须与转型后的实例类型相同。[见示例5]

两种转型区别:

若想操作拥有共同父类的不同(子)类们的实例,就向上转型;

若想当成指定的具体的子类的实例,就向下转型。

越向上,概念越模糊,可以代表多种不同的类的实例,

越向下,概念越具体详细,可以代表特定的类的实例。

向上转型

1.定义:子类到父类的转换通常称作向上转型,通俗的说就是定义父类对象指向子类对象。

  1. public class Father {
  2.   public void method() {
  3.     System.out.println("父类方法,对象类型:" + this.getClass());
  4.   }
  5. }
  6.   
  7. public class Son extends Father {
  8.   public static void main(String[] args) {
  9.     Father sample = new Son();//向上转型
  10.     sample.method();
  11.   }
  12. }

结果1:

  父类方法,对象类型:class samples.Son

  这个结果没有疑问,声明的是父类的引用(句柄),但准确的调用了子类的对象,调用method,在子类中没有该方法,所以去父类中寻找到并调用之。  
      
2.Question:子类对象向上转型为父类实例后,调用的是父类方法,还是子类方法?

Answer:

      当子类重写了父类方法,向上造成后调用的是子类方法

    子类没有重写父类方法,向上转型后调用的是父类方法。
示例2:

  1. package test;
  2.  
  3. public class HelloWorld {
  4. public static void main(String[] args) {
  5. A k=new B();
  6. k.sayHi();
  7. k.hello();
  8. }
  9. }
  10. class A {
  11. public void sayHi(){
  12. System.out.println("我是父类");
  13. }
  14. public void hello(){
  15. System.out.println("我是父类hello");
  16. }
  17. }
  18. class B extends A{
  19. public void sayHi(){
  20. System.out.println("我是子类");
  21. }
  22. }

输出结果:

我是子类
我是父类hello

示例3:

  1. package test;
  2. class Animal {
  3.  
  4. public void eat(){
  5. System.out.println("animal eatting...");
  6. }
  7. }
  8. class Bird extends Animal{
  9.  
  10. public void eat(){
  11. System.out.println("bird eatting...");
  12. }
  13.  
  14. public void fly(){
  15.  
  16. System.out.println("bird flying...");
  17. }
  18. }
  19. public class HelloWorld{
  20.  
  21. public static void main(String[] args) {
  22.  
  23. Animal b=new Bird(); //向上转型
  24. b.eat();
  25.  
  26. //! error: b.fly(); b虽指向子类对象,但此时丢失fly()方法
  27.  
  28. /*b实际指向的是Bird子类,故调用时会调用子类本身的方法。
  29.  
  30. 需要注意的是向上转型时b会遗失除与父类对象共有的其他方法。如本例中的fly方法不再为b所有。*/
  31.  
  32. }
  33.  
  34. }

 

向下转型

向下转型:将一个指向子类对象的父类引用赋给一个子类的引用,称为向下转型。注意:必须进行强制类型转换。

(应用目标场景):上面已经说到,当向上转型发生后,将无法调用子类特有的方法。但是当需要调用子类特有的方法时,可以通过将父类在转换为子类来实现。

要点:
  1.向下转型建立在向上转型的基础上[否则:转型不安全]
  2.向下转型时必须进行强制转换。
  3.父类对象(即被转型实例)强制转换类型必须与转型后的实例类型相同。[见示例5]

详解:

1.正确的向下转型

Fruit a=new Apple(); //向上转型
                    a.myName(); 
                    Apple aa=(Apple)a; //向下转型,编译和运行皆不会出错(正确的)
                    aa.myName();
                    aa.myMore();

a指向子类的对象,所以子类的实例aa也可以指向a啊~~

向下转型后因为都是指向子类对象,所以调用的当然全是子类的方法~~

2.不安全的向下转型

Fruit f=new Fruit();
               Apple aaa=(Apple)f; //-不安全的---向下转型,编译无错但会运行会出错
               aaa.myName();
               aaa.myMore();

f是父类对象,子类的实例aaa肯定不能指向父类f啊~~~

3.Java为了解决不安全的向下转型问题,引入泛型的概念

示例4:

  1. [java] view plain copy
  2. package com.sheepmu;
  3. class Fruit
  4. {
  5. public void myName()
  6. {
  7. System.out.println("我是父类 水果...");
  8. }
  9. }
  10.  
  11. class Apple extends Fruit
  12. {
  13. @Override
  14. public void myName()
  15. {
  16. System.out.println("我是子类 苹果...");
  17. }
  18. public void myMore()
  19. {
  20. System.out.println("我是你的小呀小苹果~~~~~~");
  21. }
  22. }
  23.  
  24. public class Sys{
  25. public static void main(String[] args) {
  26. Fruit a=new Apple(); //向上转型
  27. a.myName();
  28.  
  29. Apple aa=(Apple)a; //向下转型,编译和运行皆不会出错(正确的)
  30. aa.myName();//向下转型时调用的是子类的
  31. aa.myMore();;
  32.  
  33. Fruit f=new Fruit();
  34. Apple aaa=(Apple)f; //-不安全的---向下转型,编译无错但会运行会出错
  35. aaa.myName();
  36. aaa.myMore();
  37. }
  38. }

输出:

我是子类  苹果...
我是子类  苹果...
我是你的小呀小苹果~~~~~~
Exception in thread "main" java.lang.ClassCastException: com.sheepmu.Fruit cannot be cast to com.sheepmu.Apple
at com.sheepmu.Sys.main(Sys.java:30)

示例5:

public class Test{ 
   Animal animal=new Dog(); 
   Dog dog=(Dog)animal;//向下转型,强制转换为狗狗对象 
   Cat cat=(Cat)animal;//运行出错
}

注解:

[1]运行时绑定也叫动态绑定,它是一种调用对象方法的机制。Java调用对象方法时,一般采用运行时绑定机制。

  1.Java的方法调用过程

  编译器查看对象的声明类型和方法名(对象变量的声明类型)。通过声明类型找到方法列表。

  编译器查看调用方法时提供的参数类型。

  如果方法是private、static、final或者构造器,编译器就可以确定调用那个方法。这是静态绑定。

  如果不是上述情况,就要使用运行时(动态)绑定。在程序运行时,采用动态绑定意味着:虚拟机将调用对象实际类型所限定的方法。

  2.运行时(动态)绑定的过程

  虚拟机提取对象的实际类型的方法表;

  虚拟机搜索方法签名;

  调用方法。

  注意,这里说的是对象的实际类型。即在多态的情况下,虚拟机可以找到所运行对象的真正类型。

参考文档:

Java面向对象向上转型和向下转型有什么区别?

1.【java】向上转型和向下转型:http://blog.csdn.net/lzm18064126848/article/details/47953203

2.【java】深入向上转型(动态绑定) :http://blog.csdn.net/lzm18064126848/article/details/53872332

3.Java向上转型和向下转型(附详细例子):http://blog.csdn.net/sheepmu/article/details/38327205
4.Java中的向上转型和向下转型: http://www.cnblogs.com/heyongjun1997/p/5409230.html

Java SE之向上转型(动态绑定)与向下转型的更多相关文章

  1. Java面向对象作业-用接口方式测试向下转型

    Java面向对象作业-用接口方式测试向下转型 根据视频的里实例 我们直接修改Test2测试方法: package com.java1234.chap03.sec13; public class Tes ...

  2. Java SE之向上转型与向下转型

    package object; //向上转型-向下转型 public class Up_Down_convert { /* 向上转型 * * 1.上转型对象可以使用和操作子类继承或者重写的方法 * 2 ...

  3. JAVA对象 向上转型upcasting,向下转型downcasting

    1:向上转型 向上转型,就是java多态中的父类引用指向子类对象.但要注意的是 父类引用不可以访问子类新增加的成员(属性和方法) 代码举例: /** * 定义一个父类 */ public class ...

  4. 重新精读《Java 编程思想》系列之向上转型与向下转型

    前言 今天重读了一下向上转型与向下转型,有些新的体会,了解了向上转型的好处,及如何向下转型.在此分享给大家. 向上转型 向上转型是用来表现新类和基类之间的关系.在传统中,由导出类转型成基类,在继承图中 ...

  5. Java向下转型的意义

    一开始学习 Java 时不重视向下转型.一直搞不清楚向下转型的意义和用途,不清楚其实就是不会,那开发的过程肯定也想不到用向下转型. 其实向上转型和向下转型都是很重要的,可能我们平时见向上转型多一点,向 ...

  6. Java上转型和下转型

    Java 转型问题其实并不复杂,只要记住一句话:父类引用指向子类对象. 什么叫父类引用指向子类对象,且听我慢慢道来. 从2个名词开始说起:向上转型(upcasting) .向下转型(downcasti ...

  7. Java SE/EE/ME概念理解(Java版本发展历史)

    继上一篇文章http://www.cnblogs.com/EasonJim/p/6181981.html中说的区别,其实分析的不够彻底,因此再次在这里做详细的分析. 零.Java与Sun.Oracle ...

  8. Java SE 9 新增特性

    Java SE 9 新增特性 作者:Grey 原文地址: Java SE 9 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new_ ...

  9. 从RTTI谈C++的向下转型

    转自:http://blog.chinaunix.net/uid-28541347-id-4251713.html 从RTTI谈C++的向下转型 1.什么是RTTI? RTTI 是“Runtime T ...

随机推荐

  1. ubuntu iftop工具安装和参数

    安装iftop有很多依赖关系: sudo apt-get install flex bison wget http://www.tcpdump.org/release/libpcap-1.5.3.ta ...

  2. linux shell $ 特殊变量

    $0   #Shell本身的文件名 $1-$n   #添加到Shell的各参数值.$1是第1参数.$2是第2参数… $*   #所有参数列表.如"$*"用「"」括起来的情 ...

  3. sorted新用法

  4. 英国电信反悔华为是唯一真正的5G供应商

    导读 英国电信反悔华为是唯一真正的5G供应商 英国电信的一位发言人表示,该公司目前正「从我们自 2006 年以来实施的网络架构原则中,从我们的 3G 和 4G 网络核心提取华为设备」. 英国电信已经不 ...

  5. ubuntu 程序后台运行几个方法

    51 1. 程序后加上“&” ,即 “./myjob &”, 将命令放入到一个作业队列中,可以用命令“jobs” 查看 2. 将1中的命令放在 “()”中, 即 “(./myjob & ...

  6. day9-13 linux基础

    有道云笔记链接 http://note.youdao.com/noteshare?id=207be3d6bd79e9ff2e30b160bca1fd87

  7. 自学工业控制网络之路1.1-工业控制系统发展历程CCS DCS FCS

    返回 自学工业控制网络之路 自学工业控制网络之路1.1-工业控制系统发展历程CCS DCS FCS 工业控制系统是对诸如图像.语音信号等大数据量.高速率传输的要求,又催生了当前在商业领域风靡的以太网与 ...

  8. [hgoi#2019/2/18]比较水

    T1--调换纸牌(card) Alex有 n张纸牌,每张纸牌上都有一个值ai,Alex把这些纸牌排成一排,希望将纸牌按值从小到大的顺序排好.现在他把这个任务交给你,你只能进行一种操作:选中一张牌,然后 ...

  9. POJ1163(简单的DP)

    题目链接:http://poj.org/problem?id=1163 Description 73 88 1 02 7 4 44 5 2 6 5 (Figure 1) Figure 1 shows ...

  10. jquery&bootstrap

    学会了用bootstarp和jquery的引用,布局就简单多了,但就是不怎么自由,必须按照固定的来: 引用文件: <script type="text/javascript" ...