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

什么叫父类引用指向子类对象?

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

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

第 1 个例子:

Father f1 = new Son(); // 这就叫 upcasting (向上转型) // 现在 f1 引用指向一个Son对象 Son s1 = (Son)f1; // 这就叫 downcasting (向下转型) // 现在f1 还是指向 Son对象

第 2 个例子:

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

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

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

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

总结:

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

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

Father f1 = new Son();

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

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

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

一、向上转型。

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

1、向上转型中的方法调用:

实例

 1 public class Animal {
 2
 3   public void eat(){
 4     System.out.println("animal eatting...");
 5   }
 6 }
 7 class Bird extends Animal{
 8
 9   public void eat(){
10     System.out.println("bird eatting...");
11   }
12
13   public void fly(){
14
15     System.out.println("bird flying...");
16   }
17 }
18 class Main{
19    public static void doEat(Animal h) {
20     h.eat();
21   }
22   public static void main(String[] args) {
23
24     Animal b=new Bird(); //向上转型
25     b.eat();
26     //! error: b.fly(); b虽指向子类对象,但此时丢失fly()方法
27     Animail c1=new Animal();
28     Bird c2=new Bird();
29     doEat(c1);
30     doEat(c2);//此处参数存在向上转型
31   }
32 }

转型

注意这里的向上转型:

Animal b=new Bird(); //向上转型 b.eat();

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

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

2、向上转型的作用

看上面的代码:

public static void doEate(Animail h) { h.sleep(); }

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

二、向下转型。

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

实例

public class Animail {private String name="Animail";public void eat(){System.out.println(name+" eate");}
}class Human extends Animail{private String name="Human";public void eat(){System.out.println(name+" eate");}
}class Main {public static void main(String[] args) {Animail a1=new Human();//向上转型Animail a2=new Animail();Human b1=(Human)a1;// 向下转型,编译和运行皆不会出错//       Human c=(Human)a2;//不安全的向下转型,编译无错但会运行会出错
    }
}实例

实例

Animail a1=new Human();//向上转型
Human b1=(Human)a1;// 向下转型,编译和运行皆不会出错

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

Animail a2=new Animail();
Human c=(Human)a2;//不安全的向下转型,编译无错但会运行会出错
 

运行出错:

Exception in thread "main" java.lang.ClassCastException: study.转型实例.Animail cannot be cast to study.转型实例.Human
at study.转型实例.Main.main(Main.java:8)

向下转型的作用

向上转型时 b会遗失除与父类对象共有的其他方法;可以用向下转型在重新转回,这个和向上转型的作用要结合理解。

三、当转型遇到重写和同名数据

看下面一个例子,你觉得它会输出什么?

public class A {public int i=10;void print(){System.out.println("我是A中的函数");}
}
class B extends A{public int i=20;void print(){System.out.println("我是B中的函数,我重写了A中的同名函数");}void speek(){System.out.println("向上转型时我会丢失");}public static void main(String[] args) {B b=new B();A a=b;//此处向上转型
        b.print();  System.out.println(b.i);b.speek();a.print();  System.out.println(a.i);((B) a).speek();//a在创建时虽然丢失了speek方法但是向下转型又找回了
}
}

结果

我是B中的函数,我重写了A中的同名函数
20
向上转型时我会丢失
我是B中的函数,我重写了A中的同名函数
10
向上转型时我会丢失

结果

我们发现同名数据是根据创建对象的对象类型而确定,而这个子类重写的函数涉及了多态,重写的函数不会因为向上转型而丢失

多态存在的三个必要条件

  • 继承
  • 重写
  • 父类引用指向子类对象

所以不要弄混淆了,父类的方法在重写后会被子类覆盖,当需要在子类中调用父类的被重写方法时,要使用super关键字

转载于:https://www.cnblogs.com/xiaoyezideboke/p/10939219.html

Java 转型问题(向上转型和向下转型)相关推荐

  1. Java 接口及向上造型和向下造型

    学习内容: Java 接口及向上造型和向下造型 前言 学习 JAVA 大数据:"钱"景无限 文章目录 一:Java 接口 二:向上造型和向下造型 三:总结 一:Java 接口 a. ...

  2. java 向下转型运行时错误_8.5.2 向下转型与运行类型异常

    由于向下转型(在继承层次中向上移动)会丢失聚类的类型信息,所以我们就想,通过向下转型-也就是在继承层次中向下移动-应该能够获取类型信息.然而,我们知道向上转型是安全的,因为基类不会具有大于导出类的接口 ...

  3. java 向下转型有什么用_java向下转型,有啥作用。求解

    java向下转型,有啥作用.求解 关注:197  答案:2  mip版 解决时间 2021-01-25 08:10 提问者删除记忆里的你 2021-01-25 03:12 java向下转型,有啥作用. ...

  4. Java向下转型以及如何判断能否向下转型

    上一条博客中我们一起了解了Java向上转型的意思以及它的优点,但同时也知道了在向上转型的过程中子类对象将不能调用其独有的方法.那我们怎么样才能既实现向上转型,又能使子类可以调用其独有的方法呢,这就需要 ...

  5. java的向下转型_终于搞明白向下转型的作用了,还不懂的进来看下.

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 之前一直搞不明白,向下转型的实际意义,虽然知道向下转型怎么写, 现在我来讲解下 向下转型 的实际作用,如果有错的话,大家可以指出, 如果认为我说的对的话可 ...

  6. java 向下转型运行时错误_java多态和向下转型问题。

    Q1:运行结果中dog2和dog3的引用都指向Dog,且引用地址都一样,但是为什么dog2为什么就不能用eat(i)方法呢?Q2:为什么运行结果都是true?Q3:我开始是Animalsdog2=ne ...

  7. 【Java挠头】继承、抽象、接口、多态、向上转型、向下转型等精妙干货

    –本文摘要–     1.本文的目标读者:是了解Java基础,且对面向对象概念有所了解,但是对Java中继承.抽象类.接口.多态等等概念搞不清的初学者.     2.本文的内容摘要:讲述Java中的一 ...

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

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

  9. java 使用class转型_java中向上转型(upcast)和向下转型(downcast)

    先看下面的程序: class Useful { int value = 20; public void f() {System.out.println("f() in the Useful ...

最新文章

  1. linux kernel内存管理学习篇
  2. Kubernetes从懵圈到熟练:认证与调度
  3. 什么是windows10的Shell Infrastructure Host
  4. matlab 功率谱密度 汉宁窗_[振动与测试 2] 什么是PSD(功率谱密度)
  5. webpack打包非模块化js
  6. 民营银行是怎样炼成的:优中选优最终挑选出5家
  7. 基于matlab的电池管理系统开发,使用 Simulink 和基于模型的设计开发电池管理系统...
  8. 微信小程序服务器配置流程 免费开启HTTPS
  9. ipad pro能用python编程吗_涨知识!iPad还可以运行Python代码
  10. 统信自带浏览器js不兼容问题
  11. 5G无线技术基础自学系列 | 5G RAN网络架构关键技术
  12. vijos- P1385盗窃-月之眼 (水题 + python)
  13. Unity Loading转场学习笔记
  14. 服务器开虚拟机总是gpu满载,vSphere 环境机器学习 GPU 加速方案选型
  15. azure不支持哪些语句 sql_SQL Azure vs SQL Server
  16. 关闭selinux的方法汇总
  17. Photoshop CS2 9.0算号器
  18. 计算机应用与jaj,基于J2EE银鸽集团ERP系统的设计与应用-计算机应用技术专业论文.docx...
  19. linux修改时间命令
  20. 【梯度下降法】Python 梯度下降法拟合正弦曲线 多项式函数傅里叶函数

热门文章

  1. pg数据库生成随机时间_如何测试数据库查询优化器
  2. 轴只显示5个刻度_组团投资5亿元!武平集中签约5个新型显示产业链投资项目
  3. shardingjdbc每月分表_shardingjdbc分库分表测试
  4. mysql 安装dso命令_LAMP环境搭建
  5. 在线提交信息 程序 php,在线短消息收发的程序,不用数据库_php基础_脚本
  6. mac设置计算机用户名,如何更改macbook用户名_高手教你更改macbook用户名的方法-系统城...
  7. 乌鲁木齐计算机老师待遇,如果月薪超过10000元,安排去新疆当教学教师,愿意吗?...
  8. java ee 3.0_初识JavaEE 6 的 Servlet3.0
  9. Python2.7连接MySQL5.7 附demo
  10. cms php vue 开源_骑士CMS文件包含+getshell