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

news2025/1/9 10:16:39

目录

一.向上转型

直接赋值 

总结:

通过传参

通过返回值

二.向下转型

instanceof 


一.向上转型

向上转型其实就是创建一个子类对象,并将其当作父类对象来使用,一般语法格式如下:

父类类型 对象名 = new 子类类型()

一般有以下三种使用场景:

直接赋值 

我们这里以父类为Animal类举例,并且有一个Cat类来继承他 

class Animal {
    String name;
    int age;
    //构造方法
    public Animal(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public void eat() {
        System.out.println(this.name + "正在吃食物~~~");
    }
}
class Cat extends Animal {
    //构造方法
    public Cat(String name,int age) {
        super(name,age);
    }
}

        在这种情况下,我们用父类对象直接引用子类对象,不但程序不会报错,反而还可以正常调用父类中的成员方法

    public static void main(String[] args) {
        Cat cat = new Cat("布偶",3);
        Animal animal1 = cat;
        animal1.eat();
        
        Animal animal2 = new Cat("橘猫",2);
        animal2.eat();
    }

输出结果: 

那能不能调用子类的成员方法呢?我们在子类中新添加一个sleep方法

class Animal {
    String name;
    int age;
    //构造方法
    public Animal(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public void eat() {
        System.out.println(this.name + "正在吃食物~~~");
    }
}
class Cat extends Animal {
    //构造方法
    public Cat(String name,int age) {
        super(name,age);
    }
    //新添加的子类方法
    public void sleep() {
        System.out.println(this.name + "正在睡觉......");
    }
}

我们尝试用上述过程来调用以下子类的中的方法:

    public static void main(String[] args) {       
        Animal animal = new Cat("橘猫",2);
        animal.eat();
        animal.sleep();   
    }

但是等我们写好了后,就会发现编译器报错了 

也就是说:

使用向上转型后,我们可以正常调用父类中的成员方法,但是不能调用子类中自己的方法

但是要解决上述问题还是很简单的,当我们在子类中重写父类方法后,我们就可以调用子类方法了,这也就是我们多态的实现

class Animal {
    String name;
    int age;
    //构造方法
    public Animal(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public void eat() {
        System.out.println(this.name + "正在吃食物~~~");
    }
    public void sleep() {
    }
}
class Cat extends Animal {
    //构造方法
    public Cat(String name,int age) {
        super(name,age);
    }
    public void sleep() {
        System.out.println(this.name + "正在睡觉......");
    }
}
    public static void main(String[] args) {
        
        Animal animal = new Cat("橘猫",2);
        animal.eat();
        animal.sleep();
        
    }

现在我们就可以正常调用输出了:

总结:

当我们通过向上转型新建了一个对象后,我们可以通过这个对象来访问父类中的方法,但是不能访问子类中自己的方法,除非我们在子类中重写父类方法,也就是说当一个方法只有在父类和子类中都出现的情况下,我们才能访问子类中的这个方法

通过向上转型新建的对象可以访问的方法范围是:

  • 父类有 子类没有
  • 父类有 子类也有 

不能访问的范围是

  • 父类没有 子类也没有
  • 父类没有 但子类有 

通过传参

class Animal {
    String name;
    int age;
    //构造方法
    public Animal(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public void eat() {
        System.out.println(this.name + "正在吃食物~~~");
    }
}
class Dog extends Animal {
    //构造方法
    public Dog(String name,int age) {
        super(name,age);
    }
    public void eat(){
        System.out.println(this.name + "正在吃狗粮~~~");
    }
}
class Cat extends Animal {
    //构造方法
    public Cat(String name,int age) {
        super(name,age);
    }
    public void eat(){
        System.out.println(this.name + "正在吃猫粮~~~");
    }
}
    public static void fun(Animal animal) {
        animal.eat();
    }
fun(new Dog("哈士奇",2));
fun(new Cat("橘猫",2));

 我们通过一个方法来接受一个父类对象,然后通过这个父类对象来调用eat方法,当我们传入的参数是一个子类对象的时候,就相当于我们用父类对象做参数来接到了子类对象,也就是发生了向上转型

输出结果:

通过返回值

class Animal {
    String name;
    int age;
    //构造方法
    public Animal(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public void eat() {
        System.out.println(this.name + "正在吃食物~~~");
    }
}
class Dog extends Animal {
    //构造方法
    public Dog(String name,int age) {
        super(name,age);
    }
    public void eat(){
        System.out.println(this.name + "正在吃狗粮~~~");
    }
}
class Cat extends Animal {
    //构造方法
    public Cat(String name,int age) {
        super(name,age);
    }
    public void eat(){
        System.out.println(this.name + "正在吃猫粮~~~");
    }
}
    public static Animal fun1(Animal animal) {
        return new Cat("布偶",3);
    }
    public static Animal fun2(Animal animal) {
        return new Dog("哈士奇",2);
    }

我们用父类对象做返回值类型,但是我们返回的是子类对象,这也就相当于发生了向上转型

向上转型的优点:让代码实现更简单灵活。
向上转型的缺陷:不能调用到子类特有的方法 

二.向下转型

将一个子类对象经过向上转型之后当成父类方法使用,再无法调用子类的方法,但有时候可能需要调用子类特有的方法,此时:将父类引用再还原为子类对象即可,即向下转换

 

class Animal {
    String name;
    int age;
    //构造方法
    public Animal(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public void eat() {
        System.out.println(this.name + "正在吃食物~~~");
    }
    public void sleep() {
    }
}
class Cat extends Animal {
    //构造方法
    public Cat(String name,int age) {
        super(name,age);
    }
    public void sleep() {
        System.out.println(this.name + "正在睡觉......");
    }
}
public class Test_4 {
    public static void main(String[] args) {
        Animal animal = new Cat("橘猫",2);
        Cat cat = new Cat("布偶",2);
        animal.eat();
        animal.sleep();
        cat = (Cat)animal;
        cat.eat();
        cat.sleep();
    }
}

 输出结果:

instanceof 

向下转型用的比较少,而且不安全,万一转换失败,运行时就会抛异常。Java中为了提高向下转型的安全性,引入了 instanceof  ,如果该表达式为true,则可以安全转换 

public static void main(String[] args) {
    Cat cat = new Cat("元宝",2);
    Dog dog = new Dog("小七", 1);
    // 向上转型
    Animal animal = cat;
    animal.eat();
    animal = dog;
    animal.eat();
    if(animal instanceof Cat) {
        cat = (Cat)animal;
    }
    if(animal instanceof Dog) {
        dog = (Dog)animal;
    }
}

对于instanceof的详细信息可以查看官方资料:

 Chapter 15. Expressions (oracle.com)

 




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

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

相关文章

【Linux】八、进程通信

进程通信的介绍 目的 数据传输:一个进程将它的数据发送给另一个进程; 资源共享:多个进程间共享资源; 通知事件:一个进程向另一个或一组进程发送消息,同时事件如,进程终止时要通知父进程&#xf…

【LeetCode刷题-二分查找】--658.找到K个最接近的元素

658.找到K个最接近的元素 方法一:二分查找双指针 假设数组长度为n,数组arr已经按照升序排序,可以将数组arr分为两部分,前一部分所有元素[0,left]都小于x,后一部分[right,n-1]都大于等于x,left与right都可以…

[C++随想录] map和set的封装

map和set的封装 1. 红黑树模版的改变1.1 RBTree类模板 头的改变1.2 封装迭代器类1.2.1 构造 && 拷贝构造1.2.2. 1.2.3. - -1.2.4. 其他运算符重载 1.3 RBTree类实现普通迭代器和const迭代器 2. set的底层逻辑3. map的底层逻辑4. 源码4.1 RBTree类4.2 set类4.3 map类 1.…

20分钟搭建Ubertooth One开源蓝牙测试工具

kali linux 2023 安装依赖(记得使用root用户搭建环境) 1、apt-get update 2、apt install ubertooth 更新共享库缓存 3、ldconfig 安装 Ubertooth 工具和驱动程序 4、插入Ubertooth One工具 5、ubertooth-util -v 备注:出现Firmwate v…

mac homebrew.mxcl.php@5.6.plist

今天启动php5.6时 遇到了一个问题 servers % brew services start php5.6 Bootstrap failed: 5: Input/output error Try re-running the command as root for richer errors. Error: Failure while executing; /bin/launchctl bootstrap gui/501 /Users/ssh/Library/LaunchAge…

【龙芯固件】ACPI——简介

一、 什么是ACPI ACPI是Hewlett-Packard, Intel, Microsoft, Phoenix, 和Toshiba共同制定的一个开放的行业规范。 ACPI由很多表组成,包括:RSDP,SDTH,RSDT,FADT,FACS,DSDT,SSDT&…

C51--PC通过串口(中断)点亮LED

B4中的:REN允许 / 禁止串行接收控制位 REN 1为允许串行接收状态。 接收数据必须开启。所以SCON:0101 0000 ;即0x50 如何知道数据已经接收 RI位:当收到数据后 RI 1(由硬件置一) 硬件置一后必须用软件…

Java 面试题之 Logback 打印日志是如何获取当前方法名称的?

在 Java 中,有四种方法可以获取当前正在执行方法体的方法名称,分别是: 使用 Thread.currentThread().getStackTrace() 方法 使用异常对象的 getStackTrace() 方法 使用匿名内部类的 getClass().getEnclosingMethod() 方法 Java 9 的 Stack…

新生儿夜惊:原因、科普和注意事项

引言: 新生儿夜惊是一种常见的现象,它可能让新父母感到焦虑和不安。夜惊通常表现为婴儿在夜间忽然惊醒、哭闹,并伴随着呼吸急促和肌肉紧张。尽管这在大多数情况下是正常的生理现象,但对于父母来说,了解夜惊的原因和适…

单链表指定结点的后插 前插操作

指定结点的后插操作 #define NULL 0typedef struct LNode {int data;struct LNode* next; }LNode, * LinkList;//后插操作:在p结点后插入元素e bool InsertNextNode(LNode* p, int e) {if (p NULL)return false;LNode* s (LNode*)malloc(sizeof(LNode));if (s N…

(一)正点原子I.MX6ULL kernel6.1移植

一、概述 学完了正点原子的I.MX6ULL移植,正点原子的教程是基于Ubuntu18,使用的是4.1.15的内核,很多年前的了。NXP官方也发布了新的6.1的内核,以及2022.04的uboot。 本文分享一下基于Ubuntu22.04(6.2.0-36-generic&…

[LeetCode周赛复盘] 第 371 场周赛20231112

[LeetCode周赛复盘] 第 371 场周赛20231112 一、本周周赛总结100120. 找出强数对的最大异或值 I1. 题目描述2. 思路分析3. 代码实现 100128. 高访问员工1. 题目描述2. 思路分析3. 代码实现 100117. 最大化数组末位元素的最少操作次数1. 题目描述2. 思路分析3. 代码实现 100124…

Flink SQL 表值聚合函数(Table Aggregate Function)详解

使用场景: 表值聚合函数即 UDTAF,这个函数⽬前只能在 Table API 中使⽤,不能在 SQL API 中使⽤。 函数功能: 在 SQL 表达式中,如果想对数据先分组再进⾏聚合取值: select max(xxx) from source_table gr…

非遗文化展示预约小程序的效果如何

漫漫历史长河,我国积累的各种非遗文化广而多,也有相应的机构整理展示和收录,区域限制下,传统非遗文化内容传播度并不高,实际线下查看了解的人也并不是很多,在实际展示方面也面临着一些难题: 线…

CS224W6.1——介绍图神经网络GNN

之前我们讨论了一些节点嵌入技术,它们可以通过随机游走的过程学习与任务无关的特征。从这篇开始,我们介绍了令人兴奋的图神经网络技术,该技术基于图结构用多层非线性变换对节点特征进行编码。图神经网络在各种任务中表现出非凡的性能&#xf…

【数据库开发】DataX开发环境的安装部署

文章目录 1、简介1.1 DataX简介1.2 DataX功能1.3 支持的数据通道 2、DataX安装配置2.1 DataX2.2 Java2.3 Python2.4 测试 3、DataX Web安装配置3.1 mysql3.2 DataX Web3.2.1 简介3.2.2 架构图3.2.3 依赖环境3.2.4 安装 结语 1、简介 DataX是阿里云DataWorks数据集成的开源版本。…

安装纯净版Linux后的必备设置

目录 一:网络设置 1,设置yum源 2,配置网络 二:samba服务设置 1,安装samba 2,设置samba 3,windows上挂载 三:安装必备的开发软件 1,GCC安装 2,Pyth…

阿里云OSS和腾讯云COS对象存储介绍和简单使用

对象存储指的是一种云存储服务,其主要是将数据以对象的形式存储在云端,并且提供了完全的API调用,这些API包括上传,下载,删除,复制,预览,权限设置等等。OSS对象存储和COS对象存储都是…

分享10个地推拉新和网推拉新app推广接单平台,一手接任务平台

文章首推平台:”聚量推客“ 官方邀请码000000 从事地推、拉新、推广这一类型的工作,是一定要有稳定的一手接单平台的,因为在瞬息万变的拉新推广市场中,很多APP应用的推广拉新存在周期性,有可能这个月还在的拉新项目&a…

【学习辅助】Axure手机时间管理APP原型,告别手机控高保真模板

作品概况 页面数量:共 30 页 兼容软件:Axure RP 9/10,不支持低版本 应用领域:时间管理、系统工具 作品申明:页面内容仅用于功能演示,无实际功能 作品特色 本品为「手机时间管理」APP原型,…