Java中的向下转型与向上转型

java转型问题其实并不复杂,只要记住一句话:父类引用指向子类对象。

什么叫父类引用指向子类对象,且听我慢慢道来.

从2个名词开始说起:向上转型(upcasting)、向下转型(downcasting).

举个例子:有2个类,Father是父类,Son类继承自Father。

Father f1 = newSon();   // 这就叫upcasting (向上转型)

// 现在f1引用指向一个Son对象

Son s1 =(Son)f1;   // 这就叫downcasting (向下转型)

// 现在f1还是指向Son对象

第2个例子:

Father f2 = newFather();

Son s2 =(Son)f2;      //出错,子类引用不能指向父类对象

你或许会问,第1个例子中:Son s1 = (Son)f1;问什么是正确的呢。

很简单因为f1指向一个子类对象,Father f1 = newSon(); 子类s1引用当然可以指向子类对象了。

而f2 被传给了一个Father对象,Father f2 = newFather();子类s1引用不能指向父类对象。

总结:

1。父类引用指向子类对象,而子类引用不能指向父类对象。

2。把子类对象直接赋给父类引用叫upcasting向上转型,向上转型不用强制转换。

     如:Father f1 = new Son();

3。把指向子类对象的父类引用赋给子类引用叫向下转型(downcasting),要强制转换。

   如:f1就是一个指向子类对象的父类引用。把f1赋给子类引用s1即 Son s1 =(Son)f1;

          其中f1前面的(Son)必须加上,进行强制转换。

一、向上转型。

通俗地讲即是将子类对象转为父类对象。此处父类对象可以是接口。

1,向上转型中的方法调用。

看下面代码:

[java]
  1. package com.wensefu.others;  
  2. public 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. class Main{  
  20.       
  21.     public static void main(String[] args) {  
  22.           
  23.         Animal b=new Bird(); //向上转型  
  24.         b.eat();   
  25.         //! error: b.fly(); b虽指向子类对象,但此时丢失fly()方法  
  26.         dosleep(new Male());  
  27.         dosleep(new Female());  
  28.     }  
  29.       
  30.     public static void dosleep(Human h) {  
  31.         h.sleep();  
  32.     }  
  33. }  
  34.                           
package com.wensefu.others;  
  1. public class Human {  
  2.     public void sleep() {  
  3.         System.out.println("Human sleep..");  
  4.     }  
  5. }  
  6. class Male extends Human {  
  7.     @Override  
  8.     public void sleep() {  
  9.         System.out.println("Male sleep..");  
  10.     }  
  11. }  
  12. class Female extends Human {  
  13.     @Override  
  14.     public void sleep() {  
  15.         System.out.println("Female sleep..");  
  16.     }  
  17. }  
  18.                           

注意这里的向上转型:
       Animal b=newBird(); //向上转型
      b.eat();

此处将调用子类的eat()方法。原因:b实际指向的是Bird子类,故调用时会调用子类本身的方法。

需要注意的是向上转型时b会遗失除与父类对象共有的其他方法。如本例中的fly方法不再为b所有。

2,向上转型的好处。

看上面的代码,

   public static void dosleep(Human h) {
      h.sleep();
    }

这里以父类为参数,调有时用子类作为参数,就是利用了向上转型。这样使代码变得简洁。不然的话,
如果dosleep以子类对象为参数,则有多少个子类就需要写多少个函数。这也体现了JAVA的抽象编程思想。

二、向下转型。

与向上转型相反,即是把父类对象转为子类对象。

看下面代码:

package com.wensefu.other1;  
  1. public class Girl {  
  2.     public void smile(){  
  3.         System.out.println("girl smile()...");  
  4.     }  
  5. }  
  6. class MMGirl extends Girl{  
  7.       
  8.     @Override  
  9.     public void smile() {  
  10.           
  11.         System.out.println("MMirl smile sounds sweet...");  
  12.     }  
  13.     public void c(){  
  14.         System.out.println("MMirl c()...");  
  15.     }  
  16. }  
  17. class Main{  
  18.       
  19.     public static void main(String[] args) {  
  20.           
  21.         Girl g1=new MMGirl(); //向上转型  
  22.         g1.smile();  
  23.           
  24.         MMGirl mmg=(MMGirl)g1; //向下转型,编译和运行皆不会出错  
  25.         mmg.smile();  
  26.         mmg.c();  
  27.           
  28.           
  29.         Girl g2=new Girl();  
  30. //      MMGirl mmg1=(MMGirl)g2; //不安全的向下转型,编译无错但会运行会出错  
  31. //      mmg1.smile();  
  32. //      mmg1.c();  
  33.   
  34.         if(g2 instanceof MMGirl){  
  35.             MMGirl mmg1=(MMGirl)g2;   
  36.             mmg1.smile();  
  37.             mmg1.c();  
  38.         }  
  39.           
  40.     }  
  41. }  

Girl g1=new MMGirl(); //向上转型
      g1.smile();
      MMGirl mmg=(MMGirl)g1; //向下转型,编译和运行皆不会出错

这里的向下转型是安全的。因为g1指向的是子类对象。


Girl g2=new Girl();
MMGirl mmg1=(MMGirl)g2; //不安全的向下转型,编译无错但会运行会出错

运行出错:

Exception in thread "main"java.lang.ClassCastException: com.wensefu.other1.Girl
    atcom.wensefu.other1.Main.main(Girl.java:36)
如代码所示,可以通过instanceof来防止出现异常。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/549314.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

细粒度审计 FGA

传统的 Oracle 数据库审计选件允许您在宏观级别上跟踪用户在对象上所执行的操作 — 例如,如果您审计对某个表的 SELECT 语句,则可以跟踪是谁从表中选择了数据。但是,您不知道他们选择了什么。利用数据操纵语句 — 如 INSERT、UPDATE 或 DELET…

矩阵连乘问题的算法分析

问题描述:给定n个矩阵:A1,A2,...,An,其中Ai与Ai1是可乘的,i1,2...,n-1。确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少。输入数据为矩阵个数和每个矩阵规模&…

等一分钟看了会流泪

转载于:https://blog.51cto.com/hljheiwangwei/269127

Silverlight 解谜游戏 之十六 消失的蒙娜丽莎

在《Silverlight 解谜游戏 之三 消除名单》中我们通过在物品轮廓画出Path 来达到消除物品的效果,由于游戏中的物品都是Office 图片的一部分所以无法使其真正消失,本篇我们将添加一个独立于Office 图片的物品,使其能动态消失。 看看题板上多出…

明令禁止工作“996”,是对“生而为人”的基本尊重

离GitHub上996.ICU项目的发布时间已过去好一段时间了,作为一名计算机专业的在读生,对996有一点体会,最直观的体会就是为了提升技术,连续一个学期在实验室工作超过10个小时。 人民日报发文《被“996”围困的年轻人,像是…

ASP.NET教程5

添加方法,在Sql Server创建表,主表与外键表关联,在asp.net中如何绑定下拉式选单DropDownList,并如何重构DropDownList Web控件,创建SELECT与Insert存储过程,以及应用Transaction事务。 文件格式&#xff1a…

火柴 UVa11375

1.题目描述:点击打开链接 2.解题思路:本题利用递推关系解决。首先可以把“已经使用过的火柴数i”看做状态,可以得到一个图,从前往后每添加一个数字x,就从状态i转移到了ic[x],其中c[x]代表数字x需要的火柴数…

EntitySpaces2009的开发文档地址

EntitySpaces2009的开发文档地址,开发文档做得还是很不错的,主要的和关键的问题都在其中说明了,比示例做得好。 http://developer.entityspaces.net/documentation/Default.aspx转载于:https://www.cnblogs.com/Rising/archive/2010/01/31/16…

ACM 博弈专题(5种模板)

最近算法课在学博弈论的知识,顺手把算法题中的涉及到博弈论一并总结了 这篇文章的有些内容是参考了大佬的 可能有遗漏。。。。 (一)巴什博弈(BAsh Game) 题目模板 只有一堆n个物品两个人轮流取,每次只能取1~m个物品,谁先取完&am…

让sky Driver成为你的可见硬盘

网盘就不用多说了,国内国外的都很多,但是sky Driver以25G的大容量还是吸引着我,看来还是盖茨比较称钱(sorry,方言,意思就是nb的意思),但是一向以用户体验非常不错著称的microsoft在这…

初学博弈论

一、巴什博奕(Bash Game) 基本描述&#xff1a; 只有一堆n个石子&#xff0c;两个人轮流从这堆石子中取石子&#xff0c;规定每次至少取一个&#xff0c;最多取m个&#xff0c;最后取完的人获胜。 分析&#xff1a; 当n < m的时候&#xff0c;显然先手获胜&#xff0c;因…

设计模式----Adapter(适配器)

作用: 将一个类的接口转换成客户希望的另外一个接口。Adapt 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 UML示意图 1)采用继承原有接口类的方式 2)采用组合原有接口类的方式 解析: Adapt模式其实就是把完成同样的一个功能但是接口不能兼容的类桥接在一起…

浅谈算法——博弈论

注&#xff1a;下列游戏都建立在双方都有最优策略的情况下&#xff0c;若未加以说明&#xff0c;则每人每次至少取一个石子。 例1&#xff1a;取石子游戏之一 有两个游戏者&#xff1a;A和B。有n颗石子。 约定&#xff1a;两人轮流取走石子&#xff0c;每次可取1、2或3颗。A先…

linux系统管理学习笔记之八---进程与作业的管理

linux系统管理学习笔记之八---进程与作业的管理 2010-01-05 13:00:42标签&#xff1a;linux 进程    [推送到技术圈] 版权声明&#xff1a;原创作品&#xff0c;允许转载&#xff0c;转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。ht…

C++中的srand(time(null))利用时间设置随机种子产生随机数

首先需要声明的是&#xff0c;计算机不会产生绝对随机的随机数&#xff0c;计算机只能产生“伪随机数”。其实绝对随机的随机数只是一种理想的随机数&#xff0c;即使计算机怎样发展&#xff0c;它也不会产生一串绝对随机的随机数。计算机只能生成相对的随机数&#xff0c;即伪…

srand(设置随机数种子)

srand&#xff08;设置随机数种子&#xff09; 相关函数rand&#xff0c;random srandom 表头文件#include<stdlib.h> 定义函数void srand (unsigned int seed); 函数说明srand()用来设置rand()产生随机数时的随机数种子。参数seed必须是个整数&#xff0c;通常可以利用g…

Exchange 2003升级至Exchange 2007

环境: 三台机器:DC Exchange2003 Exchange2007 计算机名:DC MAIL NEWMAIL 前提条件: 1.Exchange组织设置为纯模式。 2.Exchange 2003安装SP2 3.拥有Schema Master角色的DC及所有GC运行在Windows 2003 SP1或更高以上 4.AD域提升到最高 不被Exchange 2007支持的组件有: Nov…

蓝桥杯 标题:纵横火柴旗子

【编程题】这是一个纵横火柴棒游戏。如图[1.jpg]&#xff0c;在一个3x4的方格中&#xff0c;游戏的双方轮流放置火柴棒。其规则是&#xff1a;1. 不能放置在已经放置火柴棒的地方&#xff08;即只能在空格中放置&#xff09;。2. 火柴棒的方向只能是垂直或水平放置。3. 火柴棒不…

易语言源代码毁来者来了!!

2009年12月7号16:34分&#xff0c;恐怖现象在次出现了&#xff01; 在编译易程序时&#xff0c;突然提示&#xff0c;某某模块找不到了&#xff0c;我跑到软件目录下一看&#xff0c;妈啊不得了&#xff0c;目录中一百多个文件能删除的全部都被删除了&#xff0c;只剩余几个残破…

矩阵连乘 动态规划 详解

矩阵连乘问题----动态规划(转载)&#xff1a; 给定n个矩阵&#xff5b;A1,A2,…,An&#xff5d;&#xff0c;其中Ai与Ai1是可乘的&#xff0c;i1&#xff0c;2…&#xff0c;n-1。如何确定计算矩阵连乘积的计算次序&#xff0c;使得依此次序计算矩阵连乘积需要的数乘次数最少。…