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

目录

一.向上转型

直接赋值 

总结:

通过传参

通过返回值

二.向下转型

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)

 




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

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

相关文章

13. 高精度延时

13. 高精度延时 GPT 定时器简介GPT 定时器结构GPT 定时器工作模式 GPT 定时器相关寄存器GPTx_CRGPTx_PRGPTx_SRGPTx_CNTGPTx_OCR GPT 配置步骤程序编写bsp_delay.hbsp_delay.cmain GPT 定时器简介 GPT 定时器是一个 32 位向上定时器,也就是从0x00000000 开始向上递…

CCF ChinaSoft 2023 论坛巡礼 | CCF-华为胡杨林基金-形式化方法专项(海报)论坛

2023年CCF中国软件大会(CCF ChinaSoft 2023)由CCF主办,CCF系统软件专委会、形式化方法专委会、软件工程专委会以及复旦大学联合承办,将于2023年12月1-3日在上海国际会议中心举行。 本次大会主题是“智能化软件创新推动数字经济与社…

Java实现音频转码,WAV、MP3、AMR互转

1.背景 最近在集成一款产品支持语音双向对讲,首先是采集小程序的音频下发给设备端,然后可以控制设备录音生成音频链路让小程序播放。在这个过程中发现,设备除了AMR格式的音频外,其他的音频都不支持,而微信小程序有不支…

LangChain应用全解析

一、Langchain基础 1.Langchain简介 (1)替换模型 from langchain.prompts import ChatPromptTemplatechat ChatOpenAI(temperature0) 使用代理ip llm ChatOpenAI(model_name"gpt-3.5-turbo", max_tokens2048, temperature0.5,openai_api_keyapi_key,openai_ap…

docker stop slow 解决

验证 NanoMQ stop slow 的问题 daemon 和非 daemon 两种方式 docker stop 都很慢 疑问是默认情况下,SIGTERM 会被处理。 模拟 docker 内发送 SIGTERM 信号 # The default signal for kill is TERM # pkill will send the specified signal (by defau…

海康Visionmaster-环境配置:CSharp 二次开发环境配 置方法

C#二次开发环境的配置方法 以 WinForm 为例,进行 VM 二次开发的环境配置分为三步: 第一步,使用 VS 新建一个框架为.NET Framework 4.6.1 的工程,平台首选 32 位取消勾选,重新生成解决方案,保证工程 Debug 下…

c++ 信奥编程 1135:配对碱基链

#include<iostream> #include<cstdio> #include<cstring> using namespace std; int main(){char a[256];int len;int i;gets(a);lenstrlen(a);//计算字符串长度for(i0; i<len; i){ //输出配对碱基if(a[i]A) cout<<"T";if(a[i]T) cout<…

【java:牛客每日三十题总结-6】

java:牛客每日三十题总结 总结如下 总结如下 transient 变量和序列化有关&#xff0c;这是一个空接口&#xff0c;起标记作用&#xff0c;具体的序列化由ObjectOutputStream和ObjectInputStream完成。transient修饰的变量不能被序列化&#xff0c;static变量不管加没加transie…

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

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

开放领域问答机器人2——开发流程和方案

开放领域问答机器人是指在任何领域都能够回答用户提问的智能机器人。与特定领域问答机器人不同&#xff0c;开放领域问答机器人需要具备更广泛的知识和更灵活的语义理解能力&#xff0c;以便能够回答各种不同类型的问题。 开发开放领域问答机器人的流程和方案可以包括以下步骤…

Pytroch损失函数、反向传播和优化器、Sequential使用

Pytroch_Sequential使用、损失函数、反向传播和优化器 文章目录 nn.Sequential搭建小实战损失函数与反向传播优化器 nn.Sequential nn.Sequential是一个有序的容器&#xff0c;用于搭建神经网络的模块被按照被传入构造器的顺序添加到nn.Sequential()容器中。 import torch.nn …

[html] 动态炫彩渐变背景

废话不多说&#xff0c;直接上源码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>ZXW-NUDT: 动态炫…

交叉编译 openssl

要在 x86 平台上编译适用于 aarch64 架构的 OpenSSL 动态库&#xff0c;你需要使用交叉编译工具链。可以按照以下步骤进行&#xff1a; 安装 aarch64 交叉编译工具链&#xff1a; $ sudo apt-get install gcc-aarch64-linux-gnu g-aarch64-linux-gnu 这将安装 aarch64 交叉编…

大力说运营:如何战胜每日的头疼难题?

小美是一名微信公众号运营专员&#xff0c;近几个月来&#xff0c;每当想到去上班&#xff0c;她就感到全身无力&#xff0c;焦虑烦躁。 原来老板要求小美每天都发一篇推文&#xff0c;而且选题要有吸引力&#xff0c;经过这几个月的苦肝&#xff0c;小美感觉身体被掏空&#x…

【免费送书】蒙古包头旅游和美食推荐

【点我-这里送书】 本人详解 作者&#xff1a;王文峰&#xff0c;参加过 CSDN 2020年度博客之星&#xff0c;《Java王大师王天师》 公众号&#xff1a;JAVA开发王大师&#xff0c;专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生&#xff0c;期待你的…

JLink edu mini 10Pin接口定义

注意&#xff1a;SWD接口在阵脚2&#xff0c;4&#xff1b;而20Pin的SWD接口在阵脚7&#xff0c;9 参考&#xff1a;1 官网资料&#xff1b; 2 【润石RS0104YQ Demo开发板测试分享】J-Link EDU Mini调试5V系统_国产运算放大器_模拟开关_线性稳压器_电平转换器_小逻辑_比较器…

头歌答案HTML——基础

目录 HTML——基础 第1关&#xff1a;初识HTML&#xff1a;简单的Hello World网页制作 任务描述 第2关&#xff1a;HTML结构&#xff1a;自我简介网页 任务描述 HTML——基本标签 第1关&#xff1a;创建第一个 HTML 标签 任务描述 第2关&#xff1a;创建 任务描述 …

社会公益服务小程序的作用是什么

公益包含的项目比较广&#xff0c;包括助学、环保、关爱特殊群体等&#xff0c;市场中无论相关机构还是团队&#xff0c;都有不少&#xff0c;而在实际运作中&#xff0c;也有些一些难题&#xff1a; 首先就是信息展示方面&#xff0c;自身服务及案例难以展示&#xff0c;线上…

「题解」反转链表 返回中间节点

文章目录 &#x1f349;题目1&#xff1a;反转链表&#x1f349;解析&#x1f34c;解法一&#xff1a;创建一个新链表&#x1f34c;解法二&#xff1a;直接操作原链表 &#x1f349;题目2&#xff1a;返回中间节点&#x1f34c;解法一&#xff1a;快慢指针&#x1f34c;解法二&…

通过 Elasticsearch 和 Go 使用混合搜索进行地鼠狩猎

作者&#xff1a;CARLY RICHMOND&#xff0c;LAURENT SAINT-FLIX 就像动物和编程语言一样&#xff0c;搜索也经历了不同实践的演变&#xff0c;很难在其中做出选择。 在本系列的最后一篇博客中&#xff0c;Carly Richmond 和 Laurent Saint-Flix 将关键字搜索和向量搜索结合起…