Java多态

news2024/9/23 5:34:49

J a v a 多 态 \color{black}{\huge{Java多态}} Java

多态

1. 什么是多态?

多态:同种类型的对象,执行同一个任务,会表现出不同的行为特征,这就是多态(这种解释顶级抽象)
再细致一点说多态就是为不同的数据类型提供了同一个接口。(这里这个不同数据类型一般就是指的父类与子类不同、接口类与实现类不同

在举例子之前先说一下多态的格式。

2. 多态的格式

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

实例:

//创建一个抽象动物类,其中的run()方法由子类进行重写
public abstract class Animal {

    public String name = "父类对象";
    public abstract void run();
}

//狗类继承动物类,并且重写run()方法
public class Dog extends Animal {

    @Override
    public void run() {
        System.out.println("狗跑的非常快~~");
    }
}


//乌龟类继承动物类,并且重写run()方法
public class Tortoise extends Animal{

    @Override
    public void run() {
        System.out.println("乌龟根本跑不了!!");
    }
}


//测试类:用于多态的测试
public class Test {
    public static void main(String[] args) {
        //多态的形式: 父类类型 对象名称 = new 子类构造器;
        Animal a = new Dog();
        a.run();

        Animal a2 = new Tortoise();
        a2.run();

    }
}

观察测试类中的代码Animal a = new Dog(),Animal a2 = new Tortoise()Animal类本应该调用Animal类的对象,但是在这里调用的是两个子类的构造方法,这就是多态的体现。

3. 多态中的成员访问特点

J a v a Java Java语言中的多态设计是希望倾向于行为的多态,就像定义那样:同种类型的对象,会展现出不同的行为。所以实现多态的对象访问成员的时候特征如下:

方法调用 : 编译看左边,运行看右边
变量调用 : 编译看左边,运行也看左边(多态侧重的是行为的多态)

方法调用(多态的侧重点)

观察下面代码

Animal a = new Dog();
a.run();

Animal a2 = new Tortoise();
a2.run();

这两段代码都是Animal类创建了两个对象,但是调用构造器的时候是调用了不同子类的构造器,所以当调用run()方法的时候也是分别调用自己类的方法来运行

运行结果
在这里插入图片描述
这就是行为的多态,所谓的看左边就是创建的时候编译器是按照Animal这个类进行创建对象的。当运行方法的时候看右边就是指又要按照右边的具体子类去执行对应的方法。

变量调用

在狗类中增加以下代码:

public String name = "狗类动物";

在乌龟类中增加以下代码:

public  String name = "乌龟类动物";

两个类中的name都设定为public便于外面直接访问。

动物中原有的代码:

public String name = "父类对象";

在测试类中运行如下代码:

System.out.println(a.name);
System.out.println(a2.name);

测试结果
在这里插入图片描述
结果发现访问这两个对象的name变量,显示的结果都是打印出父类对象。这就是编译看左,运行也看左。编译的时候,左边的类就是Animal类,根本无调用的谁的构造器,自然访问name变量的时候也就只能是访问的Animal类中的name

4. 多态的优势(为什么使用多态?)

在多态形式下,右边对象可以实现解耦合,便于扩展和维护(太抽象啦这些名词)

简单来讲就是如果定义一个方法比方说go()方法,它的面向的对象就是动物对象,可以这么创建吗?

public static void go(Dog d){
	...
}

当然不可以!都已经说过了,这个go()方法是面向所有的动物创建的,这样写就是只让Dog类产生的对象使用的,肯定是不行的。
如果这样写呢?

public static void go(Animal a){
	...
}

这样写的话如果结合刚才的多态,就可以实现DogTortoise都能使用这个方法了。这就增加了方法的通用性。并且有利于维护。

原理:定义方法的时候,使用父类型作为参数,利用多态,那么该方法就可以接受父类继承产生的一切子类对象,体现出多态的扩展性和便利性。

❗❗但是直接使用多态会产生一个问题:多态下不能够使用子类独有的功能,因为编译器默认的是Animal类产生的对象,所以无法调用子类特有的功能,除了子类重写父类的方法。

5. 类型转换

其实一上来就直接那样写多态,多少让人有点懵,为什么可以那么写呢?
J a v a Java Java的类从父类开始到一层一层的子类,类的概括范围是越来越小的(从父类的大概到子类越来越来分的精细化)。所以父类的覆盖范围总是比子类要大的。再回过头看这个代码:

Animal t = new Tortoise()

Tortoise这个类作为子类范围比Animal类要小,把一个小范围的对象,赋值给一个大范围的,这一定是可以的。或者说Tortoise构造器产生的对象一定属于Tortoise 类型,但是Tortoise类型又是Animal的子类,所以上述代码是可行的。

以上就是对象自动类型转换

有自动类型转换就必然有强制类型转换

强制类型转换

将父类对象强制改变为子类类型对象,也就是将大范围强制改变为小范围(非常危险的操作属于是)。

//使用乌龟类的构造器生成动物类的对象
Animal a2 = new Tortoise();
a2.run();

//将这个动物类父类强制转换为乌龟类,然后调用乌龟类的layEgg方法
Tortoise t = (Tortoise)a2;
t.layEgg();



//乌龟类
public class Tortoise extends Animal{
    @Override
    public void run(){
        System.out.println("乌龟跑的非常的慢~~~");
    }

    /**
     * 独有功能
     */

    public  void layEgg(){
        System.out.println("乌龟在下蛋~~");
    }
}

❗❗强制类型转换可以有效解决多态的时候无法使用子类独有的方法这个问题,但是这个操作非常危险,上面的代码也是知道了这个Animal就是使用乌龟类的构造器创建的,所以才敢强转,其他的时候必须进行判断才可以强转

**注:**如果发生了转换之后的类型和对象的真实类型不是同一种类型,编译的时候不会报错,因为编译器允许有继承或者实现关系在编译阶段发生强转,但是在转换的时候就会发生ClassCastException错误

Animal t = new Tortoise();
Dog d = (Dog)t  //出现异常 ClassCastException

Instanceof

instanceof这个关键字就是解决这个问题的,使用方法:

变量名字 instanceof 真实类型
//判断关键字左边的变量指向的对象的真实类型,是否是右边的类型或者是是其子类型,是则返回true,反之

示例

if(a2 instanceof Tortoise){
      Tortoise t1 = (Tortoise) a2;
      t1.layEgg();
}else if(a2 instanceof Dog){
      Dog d = new Dog();
      d.lookDoor();
}

这样就不会出现强转范围的问题了。
这里的真实类型指的是,右边调用构造器对应的类型

强转的作用

  •      1. 可以转换成真正的子类,从而调用子类型的独有的功能
    
  •      2. 有继承关系/实现的2个类型就可以进行强制类型转换,编译没有问题
    
  •      3. 运行的时候,如果发现强制转换后的类型不是对象真实的类型就会报错
              类型转换异常:ClassCastException
    

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

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

相关文章

RK3399平台开发系列讲解(内存篇)ARM64虚拟地址空间布局

🚀返回专栏总目录 文章目录 一、虚拟地址空间划分二、用户虚拟地址空间布局三、内核地址空间布局沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 本篇章让我们一起看一下ARM64虚拟地址空间的布局。 一、虚拟地址空间划分 因为目前应用程序没有那么大的内存需求,所…

知识点9--Docker容器的数据卷

我前面介绍容器命令的时候,最后说过一个cp命令,可以把容器和宿主机之间的文件互相拷贝,保证数据的持久化,但是这种持久化偏向于比较独立完整的文件,大家有没有想过如果遇到成体系的数据保存,比如我整个数据…

精彩数据:2021年我国民旅客周转量6530亿公里,审定受理飞机2803架

2021年是特殊的一年,全体民航成员在努力克服疫情防控、经营亏损、安全压力等困难交织叠加的影响下,切实的推动了民航的高质量发展,再各项工作上都取得了较好的成绩。下面是小编使用可视化互动平台对民航发展统计报告进行报表数据处理分析后得…

超市商城小程序开发,在线盈利途径

随着消费意识的提高和零售业的不断升级,小程序已经成为目前重要的线上发展形势之一且具有很强的发展活力,在此发展机遇下,很多企业开始布局线上渠道,进入电商行业。超市作为日常生活中最常见、数量最多的线下门店,当然…

[基因遗传算法]原理思想和python代码的结合理解之(一) :单变量

读《遗传算法的Python实现(通俗易懂)》佳文的思考与笔记整理. 我们拥有一个目标函数y10⋅sin(5x)7⋅cos(4x)y10 \cdot sin(5x)7\cdot cos(4x)y10⋅sin(5x)7⋅cos(4x) def aim(x):return 10*np.sin(5*x)7*np.cos(4*x)约束范围(这里是定义域):x∈[0,5]x \…

如何选择分度带(中央子午线)

如何选择分度带(中央子午线) 发布时间:2018-01-17 版权: 同步视频教程:如何选择中央子午线或者分度带 播放 什么是中央子午线? 什么是分度带? 【百度百科】 第一步:查看你所下载(或者要套合的范围)的图像的经纬…

盘点| 爆款小游戏的开发引擎

微信推出小游戏已有4年,期间不断涌现爆款。作为可以不用下载安装直接在线玩的小程序游戏,小游戏渐渐成为不少人的心头好。今天就来盘点一下那些爆款小游戏用到的游戏开发引擎: 一、Cocos 必须得把Cocos放在第一个讲,毕竟近期的羊了…

计量经济学

计量经济学 复习题 题型:选择2*10;填空2*10;名词解释4*5;综合题10*4 一 选择填空考点 1. 截面数据,时间序列,面板数据定义。P12/1.3.3 截面数据:同一时间(时期或时点)某个…

艾美捷胆固醇肉豆蔻酸酯说明书和相关研究

艾美捷胆固醇肉豆蔻酸酯以结晶固体形式提供。储备溶液可以通过将胆甾醇肉豆蔻酸酯溶解在所选溶剂中来制备。肉豆蔻酸胆甾醇可溶于有机溶剂氯丨仿,应使用惰性气体吹扫,浓度约为10mg/ml。 艾美捷胆固醇肉豆蔻酸酯基本参数: CAS#:19…

vue中使用图像编辑器tui-image-editor(一)

vue中使用图像编辑器tui-image-editor(一) 场景:需要对图片进行旋转、缩放、裁剪、涂鸦、标注、添加文本等。 效果-图1 1、基本介绍 官网:https://ui.toast.com/tui-image-editor 官方GitHub地址:https://github.com/nhn/tui.image-edito…

数据库设计

概述 数据库设计是一项十分复杂的操作,首先需要理清数据之间的关系,绘制ER图,接着根据ER图设计Relation Schema,最后添加字段属性和索引生成数据表。一个好的ER图是一个数据库的基础。 数据库设计的好坏中最重要的一项指标就是重…

完整版在xcode打测试专用ipa包流程​

前言:有时候,想要把自己的程序运行在别人的iphone手机上,但又不能通过本地真机调试的方法安装,这个时候我们就要打一个测试专用的ipa包给远方的测试小伙伴们测试。​ 步骤:​ 首先希望你的发布证书已经安装好了。​ 1.…

分布式文件存储系统FastDFS[2]-上传和下载文件工具类

一、文件上传流程 1 时序图 2 流程说明 客户端访问Tracker Tracker 返回Storage的ip和端口 客户端直接访问Storage&#xff0c;把文件内容和元数据发送过去。 Storage返回文件存储id。包含了组名和文件名 1 添加依赖 <dependencies><dependency><groupId&g…

基于jsp+mysql+ssm峰值预警停车场管理系统-计算机毕业设计

项目介绍 随着城市建设与经济的不断发展,城市车辆的数量也不断增涨,为解决停车问题修建停车场。基于经营、安全、管理等多角度的考虑&#xff0c;希望在目前传统的大型车库管理系统中有机地结合车牌识别技术&#xff0c;以求得日后在停车库运营时更安全、管理上更细致、经营中…

13个小众有趣的网站,只有程序员才看得懂

欢迎来到程序员的世界&#xff0c;分享一些关于程序员的小众网站&#xff0c;不仅干货满满的实用类网站&#xff0c;也有一些有趣的娱乐网站&#xff0c;有些网站只有程序员才看得懂。1、程序员音乐 地址&#xff1a;https://musicforprogramming.net/ 一个仿代码样式的背景音乐…

使用JAR签名进行代码签名

JavaArchive(JAR)包格式可用于打包Java应用程序和库。 签名的JAR文件可以选择包含来自TSA时间戳响应&#xff0c;使用RFC#3161格式。 添加JAR签名者添加JAR签名者的链接&#xff0c;SignServer中的JAR签名器称为JArchiveSigner。 要配置JArchiveSigner&#xff0c;请按照以下…

[附源码]计算机毕业设计农产品销售网站Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

用R语言模拟M / M / 1随机服务排队系统

本文中我在R中构造一个简单的M / M / 1队列的离散事件模拟 。最近我们被客户要求撰写关于随机服务的研究报告&#xff0c;包括一些图形和统计输出。 模拟变量 像往常一样&#xff0c;我们从模拟及其检测所需的变量 开始。 t.end <- 10^5 # 模拟的持续时间 t.clock <- 0…

【OpenCV-Python】教程:4-3 Shi-Tomasi 角点检测

OpenCV Python Shi-Tomasi 角点检测器 【目标】 Shi-Tomasi 角点检测器cv2.goodFeaturesToTrack 【理论】 上一个章节中学习了Harris角点&#xff0c;J. Shi and C. Tomasi 做了一些修改&#xff0c;Good Features to Track显示了比Harris角点更好的效果。 Harris 角点检测…

私人定制AI绘画——快速finetune stable diffusion教程

最近AI绘图非常火&#xff0c;只需要输入文本就能得到令人惊艳的图。 举个例子&#xff0c;输入 “very complex hyper-maximalist overdetailed cinematic tribal darkfantasy closeup portrait of a malignant beautiful young dragon queen goddess megan fox with long bl…