【Java】:向上转型、向下转型和ClassCastException异常

目录

先用一个生动形象的例子来解释向上转型和向下转型

向上转型(Upcasting)

向下转型(Downcasting)

向上转型

概念

例子

发生向上转型的情况

1.子类对象赋值给父类引用

2.方法参数传递

3.返回值

向下转型

概念

注意事项

例子

ClassCastException异常

概念

例子


先用一个生动形象的例子来解释向上转型和向下转型

向上转型(Upcasting)

想象你有一个动物园,里面有各种不同类型的动物,如狮子、大象、长颈鹿等。动物园的管理员为了方便管理,给每种动物都发放了一个“动物身份证”。这个身份证上并没有详细标明是哪种动物,只是简单地标明“动物”。当管理员查看这些身份证时,他并不关心具体是哪种动物,只要知道它们是动物园里的“动物”就足够了。这就是向上转型的概念。

例子
假设你有一个Lion类(狮子类),它是Animal类(动物类)的子类。当你创建一个Lion对象,并将其赋值给一个Animal类型的引用时,就发生了向上转型。

Animal animal = new Lion(); // Lion对象被向上转型为Animal类型

在这个例子中,animal引用变量只知道它引用的是一个“动物”,而不知道具体是哪种动物。你可以通过animal引用调用Animal类中定义的方法,但不能调用Lion类中特有的方法。

向下转型(Downcasting)

现在,假设动物园的管理员需要对某种特定的动物进行特殊照顾,比如给狮子喂食特定的食物。这时,管理员需要从一堆“动物身份证”中找到狮子的身份证,并将其视为“狮子身份证”。这就是向下转型的概念。

例子
继续上面的例子,如果你想通过animal引用调用Lion类中特有的方法(比如roar()方法,表示狮子吼叫),你需要先将animal引用向下转型为Lion类型。

if (animal instanceof Lion) { // 先检查animal引用是否确实指向Lion对象  
    Lion lion = (Lion) animal; // Animal类型被向下转型为Lion类型  
    lion.roar(); // 现在可以调用Lion类中特有的方法了  
}

在这个例子中,你首先使用instanceof运算符检查animal引用是否确实指向一个Lion对象。如果是,你就可以安全地进行向下转型,并调用Lion类中特有的方法。


向上转型

概念


向上转型(Upcasting)是 面向对象编程 中的一个概念,特指将一个子类对象赋值给一个父类类型的引用变量。
这是多态性的一种体现,因为子类对象是父类的一个特例。
在Java中,向上转型是安全的,因为子类继承了父类的所有属性和方法(除了私有方法和构造方法)。

例子

假设有一个父类 Fruit 和子类 Apple

class Fruit {  
    void eat() {  
        System.out.println("Eating fruit");  
    }  
}  
  
class Apple extends Fruit {  
    @Override  
    void eat() {  
        System.out.println("Eating an apple");  
    }  
}

现在,如果我们有一个 Apple 对象,我们可以将它向上转型为 Fruit 类型:

public class Main {  
    public static void main(String[] args) {  
        Apple apple = new Apple();  
        Fruit fruit = apple; // 向上转型  
        //也可写做:Fruit fruit = new Apple();
        fruit.eat(); // 输出 "Eating an apple",因为实际调用的是 Apple 类的 eat 方法  
    }  
}

在这个例子中,Apple 类的实例 apple 被向上转型为 Fruit 类型,并赋值给 fruit 变量。

尽管 fruitFruit 类型,但由于多态性,调用 eat() 方法时实际上会执行 Apple 类中重写的 eat() 方法。

这就是向上转型和多态性的实际应用。


发生向上转型的情况


1.子类对象赋值给父类引用

当子类的实例直接赋值给父类类型的引用时,会发生向上转型。这是最常见的向上转型场景。

Apple apple = new Apple();  
Fruit fruit = apple; // 向上转型
//也可写为:Fruit fruit = new Apple();

2.方法参数传递

当向一个接受父类类型参数的方法传递一个子类对象时,也会发生向上转型。

void processFruit(Fruit fruit) {  
    // ...  
}  

Apple apple = new Apple();  
processFruit(apple); // 在这里,apple被向上转型为Fruit类型

3.返回值

如果一个方法返回一个子类对象,但是方法的返回类型是父类,那么在返回时也会发生向上转型。

Fruit getFruit() {  
    Apple apple = new Apple();  
    return apple; // 在这里,apple被向上转型为Fruit类型返回  
}

向下转型

概念


向下转型(Downcasting)是Java中类型转换的一种,它指的是将一个父类对象转换为子类类型的全过程。这个过程是显式的,需要使用强制类型转换操作符来完成。

在Java中,子类拥有父类的所有属性和方法(除了 private 修饰的属性和方法),同事还可以定义自己特有的属性和方法。

因此,当我们需要将一个父类对象当做子类对象来使用的时候,就需要进行向下转型。

注意事项

  • 向下转型的语法格式如下:
子类类型 变量名 = (子类类型) 父类对象;

  •  只能对已经进行过向上转型的对象进行向下转型:

在Java中,我们不能直接将一个父类对象强制转换为子类对象,除非这个父类对象实际上是子类对象的向上转型。也就是说,我们必须先创建一个子类对象,然后将其向上转型为父类对象,最后再进行向下转换。


  • 向下转型时需要进行类型检查:

为了避免在运行时抛出 ClassCastException 异常,我们在进行向下转型之前,通常需要使用 instanceof 运算符来检查父类对象是否可以被转换为子类类型。


  • 注意访问权限:

在向下转型后,我们可以访问子类特有的属性和方法。但是需要注意的是,如果子类中的某些属性或者方法时 private 的,那么即使进行了向下转型,也无法直接访问这些 private 成员。

例子

下面是一个简单的例子来说明向下转型的用法:

class Animal {  
    void makeSound() {  
        System.out.println("Animal makes a sound");  
    }  
}  
  
class Dog extends Animal {  
    void bark() {  
        System.out.println("Dog barks");  
    }  
}  
  
public class Main {  
    public static void main(String[] args) {  
        Animal animal = new Dog(); // 向上转型,将Dog对象转型为Animal类型  
        if (animal instanceof Dog) { // 使用instanceof进行类型检查  
            Dog dog = (Dog) animal; // 向下转型,将Animal对象转型为Dog类型  
            dog.bark(); // 调用Dog类特有的方法bark()  
        } else {  
            System.out.println("The animal is not a dog.");  
        }  
    }  
}

在这个例子中,我们首先创建了一个 Dog 对象,并将其向上转型为Animal 类型。然后,我们使用 Instanceof 运算符检查这个 Animal 对象是否可以被转换为 Dog 类型。如果可以转换,我们就进行向下转型,将 Animal 对象转换为 Dog 类型,并调用 Dog 类特有的方法 bark() 。

ClassCastException异常

概念

ClassCastException是Java中的一个运行时异常,它发生在试图将一个对象强制转换为不是其实际类型的类类型时。换句话说,当你尝试将一个对象转型为它不兼容的类型时,就会抛出此异常。

这个异常通常发生在向下转型时,如果你没有正确地检查对象的实际类型就进行转换,可能会引发ClassCastException。在Java中,向上转型是安全的,因为子类对象是父类类型的一个特例。但是,向下转型则需要显式的类型转换,并且如果不当使用,就可能导致 ClassCastException。

例子

下面是一个会导致 ClassCastException 异常的例子:

class Animal {}  
  
class Dog extends Animal {}  
  
class Cat extends Animal {}  
  
public class Main {  
    public static void main(String[] args) {  
        Animal animal = new Cat(); 
// 向上转型,Cat 是Animal的子类,所以这是安全的  
        Dog dog = (Dog) animal; 
// 尝试向下转型,但是 animal 实际上是 Cat 类型,所以会抛出 ClassCastException  
    }  
}

在这个例子中,我们创建了一个 Cat 对象,并将其赋值给 Animal 类型的变量 animal。然后,我们尝试将这个 Animal 类型的变量强制转换为 Dog 类型。但是,因为这个 Animal 对象实际上是 Cat 类型的,所以转换会失败,并抛出一个 ClassCastException

为了避免这种异常,你可以在向下转型之前使用 instanceof 操作符来检查对象是否可以被安全地转换为目标类型:

if (animal instanceof Dog) {  
    Dog dog = (Dog) animal; // 这是安全的,因为已经检查了类型  
} else {  
    System.out.println("The animal is not a dog.");  
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringSecurity的核心原理使用总结

1. SpringSecurity的核心原理 对于最原始Servlet请求处理的层次结构 客户端->过滤器链->Servlet 对于在SpringMVC中处理请求的层次结构 如何让Filter与Spring建立连接呢? 因此它增加了一个DelegatingFilterProxy 它是SpringMVC提供的的Filter,它内部代理了一个原生的F…

代码随想录——二叉树的层序遍历(Leetcode102)二叉树层序遍历的模板

题目链接 层序遍历(队列) 层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。这种遍历的方式和我们之前讲过的都不太一样。 需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用…

java项目之企业OA管理系统源码(springboot+vue+mysql)

风定落花生,歌声逐流水,大家好我是风歌,混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的企业OA管理系统。项目源码以及部署相关请联系风歌,文末附上联系信息 。 项目简介: 企业OA管理系统的主要使用…

搭建Springboot的基础开发框架-02

本系列专题虽然是按教学的深度来定稿的,但在项目结构和代码组织方面是按公司系统的要求来书定的。在本章中主要介绍下基础开发框架的功能。后续所有章节的项目全是在本基础框架的基础上演进的。 工程结构介绍 SpringbootSeries:父工程,定义一…

语言:C#

一、VSCode生成exe 二、

【计算机毕业设计】基于微信小程序校园服务平台

随着 计算机技术的成熟,互联网的建立,如今,PC平台上有许多关于校园服务方面的应用程序,但由于使用时间和地点上的限制,用户在使用上存在着种种不方便,而开发一款基于微信小程序的校园服务平台,能…

Loongnix系统替换内核操作

Loongnix系统替换内核操作 一、终端下执行命令 sudo apt search linux-image* 返回结果中格式如: linux-image-4.19.0-19-loongson-3 为最新的内核源码。 二、下载内核源码包 sudo apt source linux-image-4.19.0-19-loongson-3 如提示:E: 您必须在 sources.li…

文件系统(未打开的文件)

之前我们讲述的一些文件操作都是在文件被打开的基础上的,因为用户想要对某个文件做操作的话,这个文件一定是被打开的,也就是一定是内存级的文件。 但是有的没有被操作的文件,是在磁盘中的,我们的笔记本是在SSD中&…

红米K60Pro/K50/K40系列澎湃OS解锁BL降级出厂MIUI14稳定版本方法

最新红米K60/60pro/K50/K50至尊/K40等多个系列手机都已经推送了澎湃OS系统,但新版的系统适配周期短或者等其他原因,导致很多小伙伴希望降级回到MIUI14系统,多个小米售后都拒绝降级服务,并且官方也没有开通1个自助降级的方法&#…

rt-thread 挂载romfs与ramfs

参考: https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/tutorial/qemu-network/filesystems/filesystems?id%e4%bd%bf%e7%94%a8-romfs https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/tutor…

AI回答总不满意?你的提问方式可能完全错误!

大家好,我是卷福同学,一个专注AI大模型整活的前阿里程序员,腾讯云社区2023新秀突破作者 向AI提问想写一篇论文,结果AI就生成2000字左右的文章后就完了。小伙伴们是不是也会遇到这类情况呢。今天来教大家AI提示词的技巧&#xff0c…

FANUC机器人故障诊断—报警代码(五)

FANUC机器人故障诊断中关于报警代码的介绍更新如下: 一、报警代码(SRVO-214) SRVO-214 6轴放大器保险丝熔断 [原因]6轴伺服放大器上的保险丝(FS2,FS3)已熔断。括号内的数字表示在第几台6轴伺服放大器上检测出了保险丝熔断。 [对策] 1.保险…

实现字符串比较函数(C语言)

一、N-S流程图&#xff1b; 二、运行结果&#xff1b; 三、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>int main() {//初始化变量值&#xff1b;int i, result;char s1[100], s2[100];//填充数组&#xff1b;printf("请输入数组s1的…

java线程局部变量使用方式

线程局部变量是Java中用于存储线程本地信息的变量。这种变量仅在线程的生命周期内存在&#xff0c;并且每个线程都有自己的一份拷贝。换句话说&#xff0c;线程局部变量是线程私有的&#xff0c;其他线程无法访问。 使用场景主要包括&#xff1a; 1. 存储线程状态信息&#xff…

医疗行业面临的网络安全挑战及应对策略

网络攻击已经成为各行各业日益严重的威胁&#xff0c;但医疗行业尤其容易受到影响。2023年&#xff0c;医疗领域的黑客事件占数据泄露的79.7%。 医疗领域 虽然患者、医疗服务提供者和决策者都对保护医疗信息有所关注&#xff0c;但关键的弱点在于提供电子健康记录&#xff08;…

【数据结构与算法】力扣 111. 二叉树的最小深度

题目描述 给定一个二叉树&#xff0c;找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明&#xff1a; 叶子节点是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a; root [3,9,20,null,null,15,7] 输出&#xff1a; 2示例 2&#…

kettle从入门到精通 第五十九课 ETL之kettle 邮件发送多个附件,使用正则轻松解决

想真正学习或者提升自己的ETL领域知识的朋友欢迎进群&#xff0c;一起学习&#xff0c;共同进步。若二维码失效&#xff0c;公众号后台加我微信入群&#xff0c;备注kettle。 问题场景&#xff1a; 一个朋友说他用kettle将生成好的多个文件&#xff08;a.xls和b.xls&#xff0…

论文笔记模版

1. 摘要 1.1 背景 1.2 挑战 1.3 提出新方法 1.4 贡献 2. 引言 2.1 背景&#xff08;引出问题&#xff09; ①介绍大背景&#xff1a; ② 应用场景&#xff1a; ③ 介绍主题&#xff1a; 2.2 引出挑战 一般用图表来展现出我们的挑战&#xff08;直观&#xff0c;解决什…

[AIGC] redis 持久化相关的几道面试题

文章目录 1. 什么是Redis持久化&#xff1f;2. Redis 的持久化机制是什么&#xff1f;各自的优缺点&#xff1f;2.1 RDB&#xff08;Redis DataBase&#xff09;&#xff0c;快照2.2 AOF&#xff08;Append Only File&#xff09;&#xff0c;日志 3. 优缺点是什么&#xff1f;…

考研OS chap5 I/O管理

目录 一、I/O设备基本概念和分类 304 1.concept 2.classification &#xff08;1&#xff09;根据信息交换单位&#xff08;可能考&#xff09; 1)字符设备 2)块设备 &#xff08;2&#xff09;传输速率&#xff08;以下了解即可&#xff09; &#xff08;3&#xff09;…