Java面向对象特征之三:多态

news2025/7/20 17:41:32

一:面向对象三大特征之三:多态

1.多态是什么?

同类型的对象,执行同一个行为,会表现出不同的行为特征。

比如:猫和狗都是动物类型,执行同一个行为,但是会表现出不同的行为特征;

2.多态的常见形式

父类类型 对象名称 = new 子类构造器;
接口 对象名称 = new 实现类构造器;

例:

/*
动物类父类抽象类
 */
public abstract class Animal {
    public abstract void run();
}
/*
狗类:子类,继承动物类
 */
public class Dog extends Animal {
    @Override
    public void run() {
        System.out.println("狗恰狗粮");
    }
}
/*
猫类:子类,继续动物类
 */
public class Cat extends Animal {
    @Override
    public void run() {
        System.out.println("猫恰猫粮");
    }
}
public class PolymorphismTest {
    public static void main(String[] args) {
        //这是之前的形式
        Dog d1 = new Dog();
        d1.run();

        Cat c1 = new Cat();
        c1.run();
        System.out.println("----------------");

        /*
        多态的形式为:父类类型 对象名称 = new 子类构造器;
        例如下 右边的狗对象 赋值 给 左边的动物对象
        下方狗对象只代表单种动物类型;但是动物对象代表所有的动物,属于是小范围赋值给大范围,合情合理。
         */
        Animal d2 = new Dog();
        d2.run();

        Animal c2 = new Cat();
        c2.run();
    }
}

控制台输出结果:


3.多态中成员访问特点

方法调用:编译看左边,运行看右边;

 

如上:

1.编译阶段的时候会去到这个Animal类里找run方法 

2.找到了以后,等到运行的时候就会去Dog类里找run方法


变量调用:编译看左边,运行也看左边;(多态侧重行为多态)

  

 


4.多态的前提

需要有继承/实现关系;有父类引用指向子类对象;有方法重写。


二:多态的优势

1.优势

(1)在多态形式下,右边对象可以实现解耦合,便于扩展和维护;

没换掉之前:

 

 把🐕对象更换成🐱,run行为也会跟着改变,不需要改动代码


 (2)定义方法的时候,使用父类作为参数,该方法就可以接收这个父类的一切子类对象,体现出多态的扩展与便利;

所有动物参加赛跑比赛

public class PolymorphismTest {
    public static void main(String[] args) {
        System.out.println("---比赛开始---");
        Animal d1 = new Dog();
        go(d1);
        
        Animal c1 = new Cat();
        go(c1);
        System.out.println("吃得一样快,比赛结束,平手平手");
        
    }
    /*需求:所有动物可以一起参加比赛
     */
    public static void go(Animal a){
        a.run();
    }
}

执行原理:在上列代码中,第一步会先将狗对象的地址给到a1,然后go方法再将狗对象的地址传给形参a,形参a接收到对象地址后,根据地址去访问狗对象里的run行为。


2.多态下产生的问题

多态下不能使用子类的独有功能:

因为父类是被继承的,因此继承了父类的子类会有父类的一切行为,但是父类是没有子类独有行为的。

 

三:多态下引用类型的类型转换

1.引用类型是什么?

也就是我们自己定义的:动物类、学生类、狗类猫类等等。

2.引用类型的类型转换

自动类型转换:子类对象赋值给父类类型的变量指向。

因为父类范围大,所有子类对象赋值给父类类型的变量指向➡属于:小范围赋值给大范围,因此是自动类型转换。

强制类型转换(从父到子):

子类 对象变量 = (子类)父类类型的变量;

作用:可以解决多态下的劣势,可以实现调用子类的独有行为(方法功能)。

public class Animal {
    /*
    动物通用行为:跑
     */
    public void run(){
        System.out.println("动物可以跑^_^");
    }
}
public class Dog extends Animal{
    /*
    重写父类run方法
     */
    @Override
    public void run() {
        System.out.println("🐕跑得飞快~~");
    }
    /*
    狗类独有方法:看门
     */
    public void lookDoor(){
        System.out.println("🐕看门");
    }
}
public class Cat extends Animal{
    @Override
    public void run() {
        System.out.println("🐱跑得也很快");
    }
    public void bullyDog(){
        System.out.println("🐱在欺负🐕");
    }
}
public class PolymorphismTest {
    public static void main(String[] args) {
        System.out.println("多态下引用类型的自动类型转换:");
        Animal a1 = new Dog();
        a1.run();
//        报错,多态下不能访问子类独有功能
//        a1.lookDoor();
        System.out.println("------------");
        Animal a2 = new Cat();
        a2.run();
//        报错,多态下不能访问子类独有功能
//        a2.bullyDog();

        System.out.println("\n多态下引用类型的强制类型转换");
//        从父类类型到子类类型,大转小→必须强制类型转换
        Dog d = (Dog) a1;
        d.run();
        d.lookDoor();
        System.out.println("-------------");
//        从父类类型到子类类型,大转小→必须强制类型转换
        Cat c = (Cat) a2;
        c.run();
        c.bullyDog();
    }
}

控制台输出结果:

 注意:如果转型后的类型和对象真实类型不是同一种类型,那么在转换的时候就会出现ClassCastException

3.instanceof关键字 

Java建议多态下的引用类型在强制类型转换的前,使用 instanceof 关键字判断当前对象的真实类型,再进行强制类型转换。

变量名 instanceof 真实类型
判断 instanceof 左边的变量指向的对象的真实类型,是否与右边的类型或者与其子类类型一样,是则返回true,反之。
        Animal a3 = new Cat();
//        强制类型转换,编译阶段不报错的(注意:继承或者实现关系编译阶段可以强制,没有毛病),运行可能出错了
//        Dog dog = (Dog)a3;
//        java建议在强制转换前使用instanceof关键字判断当前对象的真实类型,再进行强制转换
        if (a3 instanceof Cat){     //判断a3指向的是不是Cat类
            Cat cat = (Cat)a3;      //是cat,强制转换成cat类,从父类类型到子类类型大转小,必须进行强制类型转换
            cat.run();              
            cat.bullyDog();
        }else if (a3 instanceof Dog){   //反之,判断a3指向是Dog则强制转换成狗类型
            Dog dog = (Dog) a3;
            dog.run();
            dog.lookDoor();
        }
        System.out.println("-------------");

 

 

        System.out.println("-------------");
        Animal a3 = new Dog();
//        强制类型转换,编译阶段不报错的(注意:继承或者实现关系编译阶段可以强制,没有毛病),运行可能出错了
//        Dog dog = (Dog)a3;
//        java建议在强制转换前使用instanceof关键字判断当前对象的真实类型,再进行强制转换
        if (a3 instanceof Cat){     //判断a3指向的是不是Cat类
            Cat cat = (Cat)a3;      //是cat,强制转换成cat类,从父类类型到子类类型大转小,必须进行强制类型转换
            cat.run();
            cat.bullyDog();
        }else if (a3 instanceof Dog){   //反之,判断a3指向是Dog则强制转换成狗类型
            Dog dog = (Dog) a3;
            dog.run();
            dog.lookDoor();
        }
        System.out.println("-------------");

 4.知识总结:

1.引用类型的类型转换,有几种方式?

自动类型转换,强制类型转换。

2.强制类型转换能解决什么问题?需要注意什么?

可以解决多态下不能访问子类独有功能的问题,强制转换后可以访问;

有继承或者实现关系的两个类型就可以进行强制转换,编译无问题;

运行时,如果发现强制转换后的类型不是对象的真实类型则会报错;

注意:Java建议强制转换前使用instanceof关键字判断一下当前对象的真实类型,再进行强制类型转换

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

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

相关文章

flink sql 源码走读 --- 解释flink jdbc where 条件为什么没有下推数据库

本文通过一个具体案例,说明 flink sql 如何实现 connector 加载、source/sink 端操作、数据库连接等。可以帮助大家了解其原理,并在代码中找到落库执行SQL生成逻辑,得到where条件并没有下推到库执行的结论。 案例如下: create t…

Zookeeper集群和Hadoop集群安装(保姆级教程)

1. HA HA(Heigh Available)高可用 解决单点故障,保证企业服务 7*24 小时不宕机单点故障:某个节点宕机导致整个集群的宕机 Hadoop 的 HA NameNode 存在单点故障的可能,需要配置 HA 解决引入第二个 NameNode 作为备份同…

C语言学习(三)

#include <stdio.h> int main(void){int a; scanf("%d",&a); printf("%d",a); return 0&#xff1b;} 正在上传…重新上传取消正在上传…重新上传取消&符号作用是把键盘中输入的值给变量a,使用scanf()时输入数值&#xff0c;需要按一下enter…

MySQL知识点全面总结2:Mysql语句的执行(DDL DML 完整性约束)

二.MySQL知识点全面总结2&#xff1a;mysql语句的执行&#xff08;DDL DML 完整性约束&#xff09; 1.对数据库的操作&#xff08;DDL&#xff09; 2.对数据表的操作&#xff08;DDL&#xff09; 3.对数据表字段的操作&#xff08;DDL&#xff09; 4.对数据表内容的增删改&…

Science Direct 高级检索、使用技巧、寻找目标期刊、E lsevi er 投稿指南

ScienceDirect使用教程&E ls evier投稿指南1. 高级检索功能1.1 布尔值运算符和短语搜索&#xff08;构建检索式&#xff09;1.2 搜索特殊字符和公式1.3 非搜索用词2. 如何使用搜索结果页面&#xff1f;3. 下载多个文档3.1 从搜索结果列表中下载多个文档3. 利用 JournalFind…

java高性能并发计数器之巅峰对决

并发计数器各个方案介绍方案概述1. jdk5提供的原子更新长整型类 AtomicLong2. synchronized3. jdk8提供的 LongAdder 【单机推荐】4. Redisson分布式累加器【分布式推荐】方案介绍jdk5提供的原子更新长整型类 AtomicLong在JDK1.5开始就新增了并发的Integer/Long的操作工具类Ato…

VS2022+qt5.14.2配置qcustomplot2.1.16(坑很多)

目录1. 前言2. 下载QCustomPlot的源码3. 将QCustomPlot添加到QT项目&#xff08;一些遇到的问题&#xff09;1. 前言 QCustomPlot 是一个超强超小巧的qt绘图类&#xff0c;非常漂亮&#xff0c;非常易用&#xff0c;只需要加入一个qcustomplot.h和qcustomplot.cpp文件即可使用…

Android 基础知识4-3.7 ProgressBar(进度条)详解

一、简介 ProgressBar&#xff08;进度条&#xff09;是UI界面中一种非常实用的组件&#xff0c;通常用于向用户像是某个耗时操作完成的百分比。进度条可动态地显示进度&#xff0c;因此避免长时间地执行某个操作时&#xff0c;让用户感觉程序失去了响应&#xff0c;从而更好地…

常用反弹 shell 方式总结

在对 Linux 系统进行渗透测试中&#xff0c;常常会用到反弹 shell 的操作&#xff0c;今天来总结一下常用反弹 shell 的方式。 什么是反弹shell&#xff1a; 反弹shell&#xff0c;就是攻击机监听在某个TCP/UDP端口为服务端&#xff0c;目标机主动发起请求到攻击机监听的端口…

Spark 配置项

Spark 配置项硬件资源类CPU内存堆外内User Memory/Spark 可用内存Execution/Storage Memory磁盘ShuffleSpark SQLJoin 策略调整自动分区合并自动倾斜处理配置项分为 3 类: 硬件资源类 : 与 CPU、内存、磁盘有关的配置项Shuffle 类 : Shuffle 计算过程的配置项Spark SQL : Spar…

MySQL 中的 distinct 和 group by 的性能比较

1 先说大致的结论&#xff08;完整结论在文末&#xff09;在语义相同&#xff0c;有索引的情况下&#xff1a;group by和 distinct 都能使用索引&#xff0c;效率相同。在语义相同&#xff0c;无索引的情况下&#xff1a;distinct 效率高于group by。原因是 distinct 和 group …

【软件开发】基于PyQt5开发的标注软件

这里是基于PyQt5写的面向目标检测的各类标注PC端软件系统。目前现有的labelme软件和labelImg开源软件无法满足特殊数据集的标注要求&#xff0c;而且没有标注顺序的报错提示。当然我设计的软件就会不具有适用性了&#xff08;毕竟从下面开发的软件可以明显看出来我做的基本上是…

spark-submit报错

spark-submit --class ${main_class} \ --master yarn \ --deploy-mode client \ --driver-memory 8g \ --executor-memory 6g \ --num-executors 1 \ --executor-cores 34 \ ${HOME_PATH}/obs_finance-1.0-SNAPSHOT-jar-with-dependencies.jar ${year_month} 注意这个34超过…

【教学典型案例】28.单表的11个Update接口--MyBatis

目录一&#xff1a;背景介绍二&#xff1a;前期准备引入pom依赖MyBatis配置文件数据库连接文件MyBatis配置类三&#xff1a;代码编写Mapper编写接口通用mapper实体pojojunit测试编写测试结果四&#xff1a;总结一&#xff1a;背景介绍 在进行项目开发编写更新接口时&#xff0…

顶级动漫IP加持之下,3A策略游戏Mechaverse如何改变GameFi

2021年是元宇宙发展的元年&#xff0c;元宇宙与GameFi创造了一波又一波市场热点。在经历第一波热潮之后&#xff0c;元宇宙的到来让不少人看到了加密市场的潜力&#xff0c;同时大家也意识到这将是未来的重要方向。如何将元宇宙推向更广阔的市场&#xff0c;让更多人能够轻松进…

项目管理工具DHTMLX Gantt灯箱元素配置教程:显示任务内容

DHTMLX Gantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表。可满足项目管理应用程序的大部分开发需求&#xff0c;具备完善的甘特图图表库&#xff0c;功能强大&#xff0c;价格便宜&#xff0c;提供丰富而灵活的JavaScript API接口&#xff0c;与各种服务器端技术&am…

神经网络(容易被忽视的基础知识)

主要内容&#xff1a; 基本神经元作为线性分类器的单个神经元为什么要是深度神经网而不是”肥胖“神经网络&#xff1f;为什么在人工神经网络中的神经元需要激活函数&#xff1f;一些主要的激活函数神经网络中的偏置有什么意义&#xff1f;初始化神经网络的参数可以全为0吗&am…

【java】java基本类型和包装类型的区别

文章目录简介1.包装类型可以为 null&#xff0c;而基本类型不可以2.包装类型可用于泛型&#xff0c;而基本类型不可以3.基本类型比包装类型更高效4.自动装箱和自动拆箱简介 Java 的每个基本类型都对应了一个包装类型&#xff0c;比如说 int 的包装类型为 Integer&#xff0c;d…

ECOLOY直接更换流程表单后导致历史流程中数据为空白的解决方案

用户反馈流历史流程打开是空白了没有内容。 一、问题调查分析&#xff1a; 工作流“XX0204 员工培训协议审批流程”workflowId37166产生的7个具体流程中&#xff0c;创建日期为2021年的4个具体流程原先引用的数据库表单应该是“劳动合同签订审批表”(formtable_main_190)&…

JavaScript-缓存

参考资料彻底解决让用户清一下浏览器缓存浏览器缓存彻底理解浏览器的缓存机制彻底弄懂前端缓存浅解强缓存和协商缓存浏览器缓存策略(强缓存和协商缓存)一文搞定Http缓存-强制缓存与协商缓存前端浏览器缓存知识梳理ASP.NET Core 中使用缓存IIS中设置Cache-Control是什么当我们第…