多态性:中的向下转型,instanceof 操作符的使用

news2024/12/28 19:54:47

多态性:中的向下转型,instanceof 操作符的使用

在这里插入图片描述


每博一文案

都说树叶不是一天变黄的,人心也不是一天变凉的,每一个现在的自己,其实都是过去的自己拼凑的。
如今我们的气质里都藏着过去走过的路,看过的书和爱过的人,曾经的好,曾经的话,曾经的眼泪和孝顺,其实一直都在,生生不息。
如今你所遇见的这个我,是被这个世界打磨过的我。正如张爱玲所说的:如果你认识从前的我,你就会
原谅现在的我呢。别人都说你变了,却没人关心你到底经历过什么。
如果我们没走过他人走过的路,经历过他人经历的事,或许真的不能懂他人的悲喜。
每个人都曾想过,要活得无忧无虑,可社会复杂,人心难测,逼的人不得不伪装将自己内心的感情藏得更深。
不敢轻易去爱,因为明白了这个迷茫的世界需要冷漠与对抗。
所以,如果你认识从前的我,也许就会理解我现在的伪装。如果你不认识从前的我,就请不要随意的随意的评判
我,因为你不知道我是怎么走到今天的往后余生。
愿你的每一次成熟都不必靠受伤才能懂得,也愿你傻傻的天真,有人会用心守。
                                                   ——————   一禅心灵庙语

文章目录

  • 多态性:中的向下转型,instanceof 操作符的使用
    • 每博一文案
    • 1. 多态: 对象类型转换
    • 2. instanceof 操作符的使用
    • 3. 总结:
    • 4. 最后:


1. 多态: 对象类型转换

基本数据类型的转换

  • 自动类型转换: 的数据类型可以自动转换成 的数据类型
long lnum = 20;        // 在Java当中整数值默认是 int 类型
double dnum = 12.0f;   // 在Java当中小数默认是 double 类型
  • 强制类型转换: 可以把 的数据类型 强制转换的数据类型
int inum = int(200L);     // L long 类型的后缀
float fnum = (float)12.0; 

对于 Java多态 引用类型(对象) 的转换:

  • 向上转型: 子类的类类型可以自动转换成 父类的类类型,被称为 向上转型,但更多是被称为 是 多态
Person person = new Student();  // 向上转型 或者 多态。
  • 强制类型转换: 可以将父类的类类型 必须通过 强制类型的转换子类 的类类型,这样就可以调用子类中特有的方法/属性了。
Person person = new Student();     // 多态
Student student = (Person)person;  // 强制向下转型

在这里插入图片描述


我们使用多态(向上转换) 为了 父类类型以后,如果想要调用 子类中特有的属性和方法 怎么办 ???

可以将 父类类型 强制转换为 对应子类 类型,从而就可以调用 子类中特有的属性和方法了。

多态:向下强制转换

如下代码:

package blogs.blog1;


public class PersonTest{
    public static void main(String[] args) {
        Person p1 = new Student();
        //p1.ncee(); // 直接编译的是父类类型,是无法调用子类中特有的属性/方法的,编译报错

        // 可以使用强制向下转型为对应 子类类型来调用其中的特有的属性/方法
        Student s1 = (Student)p1;
        System.out.println(s1.name);  // 可以调用子类中特有的属性/方法
        s1.ncee();    // 可以调用子类特有的方法


        Person p2 = new Teacher();
        Teacher t1 = (Teacher)p2;
        System.out.println(t1.name);
        t1.teach();    // 调用子类中特有的方法

    }
}

class Person {   // 父类
    String name = "Person";
    int age;

    public Person(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public Person() {

    }

    public void show() {
        System.out.println("我是 Person");
    }



}

class Student extends Person{   // 子类
    int studentId;
    String name = "Student";

    @Override
    public void show() {
        System.out.println("我是 Student");
    }

    public void ncee() {
        System.out.println("高考");
    }

}


class Teacher extends  Person{  // 子类
    int teacherId;
    String name = "Teacher";

    @Override
    public void show() {
        System.out.println("我是 Teacher");
    }


    public void teach() {
        System.out.println("教书育人");
    }
}

在这里插入图片描述


通过强制向下转型,将父类转为 对应的子类的类型,从而就可以调用子类中特有的属性/方法了。

public class PersonTest{
    public static void main(String[] args) {
        Person p1 = new Student();
        //p1.ncee(); // 直接编译的是父类类型,是无法调用子类中特有的属性/方法的,编译报错

        // 可以使用强制向下转型为对应 子类类型来调用其中的特有的属性/方法
        Student s1 = (Student)p1;
        System.out.println(s1.name);  // 可以调用子类中特有的属性/方法
        s1.ncee();    // 可以调用子类特有的方法


        Person p2 = new Teacher();
        Teacher t1 = (Teacher)p2;
        System.out.println(t1.name);
        t1.teach();    // 调用子类中特有的方法

    }
}

注意的是:使用向下强制转换,存在一个问题:就是如果两个引用类型之间没有子父类继承关系/本身的实例关系 ,而是并列关系的话,编译可以通过,但是运行时,会报:java.lang.ClassCastException 类异常。

如下代码:

package blogs.blog1;


public class PersonTest{

    public static void main(String[] args) {
        Person p1 = new Student();
        Teacher t1 = (Teacher)p1;  // 编译可以通过,但是运行时会出现异常:ClassCastException
    }

}

class Person {   // 父类
    String name = "Person";
        int age;

    public Person(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public Person() {

    }

    public void show() {
        System.out.println("我是 Person");
    }



}

class Student extends Person{   // 子类
    int studentId;
    String name = "Student";

    @Override
    public void show() {
        System.out.println("我是 Student");
    }

    public void ncee() {
        System.out.println("高考");
    }

}


class Teacher extends  Person{  // 子类
    int teacherId;
    String name = "Teacher";

    @Override
    public void show() {
        System.out.println("我是 Teacher");
    }


    public void teach() {
        System.out.println("教书育人");
    }
}
public class PersonTest{

    public static void main(String[] args) {
        Person p1 = new Student();
        Teacher t1 = (Teacher)p1;  // 编译可以通过,但是运行时会出现异常:ClassCastException
    }
}

在这里插入图片描述

报错原因:

  1. 编译不会报错是因为:我们将一个父类 Person 类型 强制向下转型为 了 Teacher 其中的一个子类,骗过了编译器,说这个类型就是这个。
  2. 运行报错是因为:编译器运行的时候,发现你给我 强制转换 过来的p1类型,与我本身 Teacher 没有任何关系,既不是 继承关系,也不是本身类的实例化。而是和我并列的 Student 类型,这样处理不对,报错: java.lang.ClassCastException

编译通过,运行不通过

public class PersonTest{
    public static void main(String[] args) {
        Person p1 = new Teacher();
        Student s1 = (Student)p1;  // 编译可以通过,但是运行时会出现异常:ClassCastException
    }
}

在这里插入图片描述

报错原因:

和上面一样。

编译不通过,运行不通过

public class PersonTest{
    public static void main(String[] args) {
        Student s1 = new Teacher();  
    }
}

在这里插入图片描述

报错原因:

左边赋值的 Student 与 右边 new 的 Teacher() 二者之间,没有继承关系,是两个并列不同的类类型,是无法相互强制赋值的。

编译无法通过,就像

String s1 = 123; 一样两个类型不一致,无法赋值。


编译通过,运行通过

直接使用对应的 向下强制转换为对应的类

public class PersonTest{
    public static void main(String[] args) {
        Person p1 = new Student();
        Student s1 = (Student)p1;   
        s1.ncee();   // Student 特有的方法

        Person p2 = new Teacher();
        Teacher t1 = (Teacher)p2;
        t1.teach();  // Teacher 特有的方法
    }
}

在这里插入图片描述


2. instanceof 操作符的使用

对应上述 强制向下转型 出现的 ClassCastException 可以预先使用 instanceof 操作符 进行一个判断。

需要注意的是: instanceof 是操作符,不是方法,所以可以直接使用,不需要导入包。

X instanceof Y 判断 X 是否是 Y的实例对象,或者 X 是否是 Y 的子类。如果是子类/是实例对象,返回 true, 不是返回 false

如下代码:

package blogs.blog1;


public class PersonTest{

    public static void main(String[] args) {
        Person p1 = new Student();
        Person p2 = new Teacher();

        System.out.println("p1 instanceof Student: "+ (p1 instanceof Student));
        System.out.println("p1 instanceof Person: "+(p1 instanceof Person));
        System.out.println("p1 instanceof Teacher: "+(p1 instanceof Teacher));

        System.out.println("***************************");

        System.out.println("p2 instanceof Teacher: "+(p2 instanceof Teacher));
        System.out.println("p2 instanceof Person: "+(p2 instanceof Person));
        System.out.println("p2 instanceof Student: "+(p2 instanceof Student));

    }

}

class Person {   // 父类
    String name = "Person";
    int age;

    public Person(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public Person() {

    }

    public void show() {
        System.out.println("我是 Person");
    }


}

class Student extends Person{   // 子类
    int studentId;
    String name = "Student";

    @Override
    public void show() {
        System.out.println("我是 Student");
    }

    public void ncee() {
        System.out.println("高考");
    }

}


class Teacher extends  Person{  // 子类
    int teacherId;
    String name = "Teacher";

    @Override
    public void show() {
        System.out.println("我是 Teacher");
    }


    public void teach() {
        System.out.println("教书育人");
    }
}

重点代码:

public class PersonTest{

    public static void main(String[] args) {
        Person p1 = new Student();
        Person p2 = new Teacher();

        // 判断 p1 是否是 Student 的实例对象/子类,是返回 true, 不是返回 false
        System.out.println("p1 instanceof Student: "+ (p1 instanceof Student)); 
        // 判断 p1 是否是 Person 的实例地下/子类,是返回 true, 不是返回 false
        System.out.println("p1 instanceof Person: "+(p1 instanceof Person));
        System.out.println("p1 instanceof Teacher: "+(p1 instanceof Teacher));

        System.out.println("***************************");

        System.out.println("p2 instanceof Teacher: "+(p2 instanceof Teacher));
        System.out.println("p2 instanceof Person: "+(p2 instanceof Person));
        System.out.println("p2 instanceof Student: "+(p2 instanceof Student));


    }
}

在这里插入图片描述


举例使用 instanceof 进行一个预先的判断,再向下强制转换

public class PersonTest{
    public static void main(String[] args) {
        Person p1 = new Student();    // 向上转型,多态

        if(p1 instanceof Student) { // 判断 p1 是否是 Student 的实例/子类,是true,强制向下转换
            Student s1 = (Student)p1;
            System.out.println(s1.studentId);   // 子类特有的属性
            s1.ncee();                          // 子类特有的方法
        }
        System.out.println("*******************");

        if(p1 instanceof Teacher) { // 判断 p1 是否是 Teacher 的实例/子类,是true,强制向下转换
            Teacher t1 = (Teacher)p1;
            System.out.println(t1.teacherId);   // 子类特有的属性
            t1.teach();                         // 子类特有的方法
        }
        
        System.out.println("*******************");
        if(p1 instanceof Person) {  // 判断p1 是否是 Person 的实例/子类,是true,强制向下转换
            Person person = (Person)p1;
            person.show();
        }
    }
}

在这里插入图片描述


3. 总结:

  1. 向上转换,称为多态
  2. 多态中:想要调用子类中特有的属性/方法,可以强制向下转型 为对应的子类。
  3. 强制向下转型可能会出现:编译正常,运行异常:java.lang.ClassCastException 类异常
  4. 可以预先使用 instanceof 预先判断再强制向下转型,防止:强制向下转型失败报错:java.lang.ClassCastException 类异常

4. 最后:

限于自身水平,其中存在的错误,希望大家给予指教,韩信点兵——多多益善,谢谢大家,江湖再见,后会有期!!!


在这里插入图片描述

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

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

相关文章

混合模式和预乘原理的理解

首先说到混合模式,简单理解,混合模式就是同一像素上有两个颜色需要混合成一个使用的模式。 这里的两个像素点,我们把原先已经存在的,也就是下面的像素点颜色定义为目标颜色。把新加上来的,也就是上面的像素点颜色定义为…

【Selenium IDE录制脚本】三分钟教会你安装Selenium IDE的安装及使用

目录 1、安装Selenium IDE 1.1、安装Firefox浏览器 1.2、安装selenium IDE 2、selenium的脚本录制 1、安装Selenium IDE 1.1、安装Firefox浏览器 因为selenium的不同版本对Firefox的支持不同,所以我们安装了Firefox之后,需要关闭他的自动更新 搜索&…

Python-Tinydb数据库详解

目录 数据库 Tinydb Tinydb 使用 安装 导入 创建数据库 创建 table 增 删 查 改 其他函数 示例 最后 数据库 数据库就是存储数据的的地方,现在我们生活中几乎每时每刻做的事可能都有它的作用。今天来介绍 Tinydb 数据库,它适合初学者&am…

设计模式概述之建造者模式(五)

常说的设计模式是23种设计模式,分为3大类: 创建型模式5种:工厂方法、抽象工厂、单例、建造者、原型 结构型模式7种:适配器、代理、桥接、装饰者、外观、享元、组合 行为型模式11种:模板方法、解释器、策略、观察者、…

【如意如意顺遂我意快快显灵】

文章目录 ● 【猿如意安装】 (基于Windows环境安装) ● 【猿如意首页】 ● 【猿如意效率工具】 ● 【猿如意开发工具】 ● 【猿如意教程文档】 ● 【猿如意一行代码】 ● 【猿如意ChatGPT】 ● 【Markdown笔记】 猿如意官网:猿…

【码极客精讲】二叉树

二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。二叉树特点…

Linux yum 命令

yum( Yellow dog Updater, Modified)是一个在 Fedora 和 RedHat 以及 SUSE 中的 Shell 前端软件包管理器。 基于 RPM 包管理,能够从指定的服务器自动下载 RPM 包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖…

Go 微服务开发框架 DMicro 的设计思路

Go 微服务开发框架 DMicro 的设计思路 DMicro 源码地址: Gitee:dmicro: dmicro是一个高效、可扩展且简单易用的微服务框架。包含drpc,dserver等 背景 DMicro 诞生的背景,是因为我写了 10 来年的 PHP,想在公司内部推广 Go, 公司内部的组件及 rpc 协议都…

Python:whl文件简介及实践

文章目录简介一、安装过程二、whl源地址推荐小结简介 WHL文件是以Wheel格式保存的Python安装包,Wheel是Python发行版的标准内置包格式。在本质上是一个压缩包,WHL文件中包含了Python安装的py文件和元数据,以及经过编译的pyd文件,…

【视觉高级篇】27 # 如何实现简单的3D可视化图表:GitHub贡献图表的3D可视化?

说明 【跟月影学可视化】学习笔记。 第一步:准备要展现的数据 可以使用这个生成数据:https://github.com/sallar/github-contributions-api 这里直接使用月影大佬的github提交数据的数据即可 结构大致如下: 第二步:用 SpriteJS…

黑*头条_第6章_kafka及异步通知文章上下架

黑*头条_第6章_kafka及异步通知文章上下架 文章目录黑*头条_第6章_kafka及异步通知文章上下架1)自媒体文章上下架2)kafka概述3)kafka安装配置4)kafka入门5)kafka高可用设计5.1)集群5.2)备份机制(Replication)6)kafka生产者详解6.1)发送类型6.2)参数详解7)kafka消费者…

小林Coding阅读笔记:操作系统篇之硬件结构,CPU Cache一致性问题

前言 参考/导流: 小林coding-2.4 CPU 缓存一致性学习意义 底层基础知识,了解CPU执行过程,让上层编码有效并发控制底层设计思维(对比 MySQL的并发控制)、更好地去理解JUC的锁、volatile以及JMM架构层面的一致性保证问…

毕业设计 单片机便携式空气质量检测仪 - 物联网 嵌入式

文章目录0 前言1 简介2 主要器件3 实现效果4 设计原理5 部分核心代码5 最后0 前言 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长…

51.`.format`字符串格式化—最适合小白的格式化笔记

51..format字符串格式化 文章目录51..format字符串格式化1.课题导入2.知识回顾3..format的基本用法3.1{}为空3.2 {}中有编号3.3 {}中有变量名4.浮点数的格式化5..format官方语法6. .format格式化语法总结7. 总结8.课堂练习1.课题导入 【描述】 用input函数输入你每个月的工资…

MySQL中WHERE后跟着N多个OR条件会怎样...

GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。GreatSQL是MySQL的国产分支版本,使用上与MySQL一致。作者:叶金荣文章来源:社区原创 可能会执行非常慢,线上生产环境千万别写出这种SQL ... 背景交…

Docker+Gitlab+Jenkins+Springboot

安装Gitlab 开放防火墙端口80和配置映射文件夹 firewall-cmd --zonepublic --add-port80/tcp --permanent firewall-cmd --reload mkdir -p /docker_data/gitlab/{data,logs,config}启动Gitlab容器(启动容器之前确保80,443端口没用被占用,被…

H3C双点双向路由引入,以及使用路由策略进行路由控制,路由学习的配置

如下拓扑中,存在两个路由域,左边为isis区域,所有设备均为level-1-2角色。右边为ospf区域,所有使能ospf的接口均在area0区域中: 组网中需要在R1和R3上,分别将各自的isis路由引入到ospf进程中,同时…

Go C 编程 第9课 放飞汽球(魔法学院的奇幻之旅 Go C编程绘图)

Goc编程第八课 Goc编程第八课_哔哩哔哩_bilibili Goc编程第九课 Goc编程第九课_哔哩哔哩_bilibili 59.实心椭圆 (魔法学院第9课) 难度:1 登录 60.双色椭圆 (魔法学院第9课) 难度:1 登录 61.气球串 (魔法学院第9课) 登录 62.同心圆环 (魔法学院第9课…

C++类与对象的应用—日期计算器

目录 一、前言 二、日期类的实现 检查日期的合法性 < 运算符重载 运算符重载 <运算符重载 >运算符重载 >运算符重载 !运算符重载 进一步优化 日期天数 日期天数 日期-天数 日期-天数 前置&&后置 前置--&&后置-- 思路&#…

强化学习的基础知识和6种基本算法解释

强化学习的基础知识和概念简介&#xff08;无模型、在线学习、离线强化学习等&#xff09; 机器学习(ML)分为三个分支:监督学习、无监督学习和强化学习。 监督学习(SL):关注在给定标记训练数据的情况下获得正确的输出无监督学习(UL):关注在没有预先存在的标签的情况下发现数据…