【JAVA基础】多态

news2024/9/21 2:43:43

文章目录

  • 多态
  • 向上转型
  • 练习题


多态

父类的引用指向子类的对象

public class A {
    public String name;
    public int age;

    public void run(){ //该run()方法被覆盖
        System.out.println("a跑的快");
    }

    public void eat(String name){
        System.out.println(name+"吃的很多");
    }
}

public class B extends A{
    public char sex;
    public double height;

    public void fly(){
        System.out.println("b飞的很高");
    }

    @Override
    public void run(){
        System.out.println("b跑的快");
    }
}

public class Test {
    public static void main(String[] args) {
        A ab = new B();  // 数据类型:决定在内存中的存储形式 ab是A类数据类型
                         // 创建子类对象前提一定会创建父类对象,此时在内存中A和B的对象都存在
        ab.name = "李四";
        ab.age = 18;
        ab.eat("张三");
        ab.run();
    }
}

以上代码中对象ab就是多态,其中:

  1. 因为ab为A类的数据类型,以A类为模板,所以他可以调用到A类中的属性

  2. ab为B类的对象,而B为A的子类,那么创建子类对象之前一定会先创建父类对象,所以ab可以访问A类中的方法

  3. 但是ab实际上指向的是子类对象的内存空间,因为受限于父类数据类型,所以只能对父类中的数据进行访问,子类中单独的数据并不能够进行访问

在这里插入图片描述

  1. ab满足了定义父类引用指向子类对象

我们看一下内存图:

创建对象ab的过程如下:

  1. ab属于B类对象,但是B类拥有A父类,那么创建子类对象之前先创建父类对象,为A类对象开辟空间,在其中存储name、age两个变量和run()、eat()两个方法
  2. 再为B类对象,其中包括sex、height两个变量和run()、fly()
  3. 因为B类为A类的子类,所以run()方法被重写,ab对象访问的话只能访问到B类中的run()方法和A中的eat()方法
  4. 因为ab为A类的数据类型,以A类为模板,所以他可以调用到A类中的属性

向上转型

在这里插入图片描述

public class C {
    public static void hanlder(A a){
        System.out.println("C的输出");
    }
}

public class Test {
    public static void main(String[] args) {
        B b = new B();
        C.hanlder(b); // 没有报错,为什么?
    }
}

在程序中,C类中的静态方法hanlder(A a)需要的参数为一个A类对象,但是在Test类中的main()方法里,我们却向方法传了一个B类的对象,编译器并没有报错,这是因为多态可以向上转型:子类的对象可以被父类所接受,也就是我们一开始说的定义:父类引用指向子类对象

练习题

A类

public class A {
    public String Show(D obj){
        return "A and D";
    }
    public String Show(A obj){
        return "A and A";
    }
}

B类

public class B extends A{
    public String Show(Object obj){
        return "B and B";
    }
    public String Show(A obj){
        return "B and A";
    }
}

C类

public class C extends B{
}

D类

public class D extends B{
}

Test类

public class Test {
    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new B();
        B b  = new B();
        C c  = new C();
        D d  = new D();

        System.out.println(a1.Show(b)); // A and A
        System.out.println(a1.Show(c)); // A and A
        System.out.println(a1.Show(d)); // A and D

        System.out.println(a2.Show(b)); // B and A
        System.out.println(a2.Show(c)); // B and A
        System.out.println(a2.Show(d)); // A and D

        System.out.println(b.Show(b)); // B and A
        System.out.println(b.Show(c)); // B and A
        System.out.println(b.Show(d)); // A and D
    }
}

我们来逐个分析一下:

首先我们可以看到A类的优先级最高,是其他BCD类的父类,B类直接继承A类,CD类直接继承B类。

  • 那么对于对象a1

    它属于A类对象,创建时只开辟A类对象的内存空间,可以调用A类中的两种Show()方法,虽然B类中有对Show方法重写,但是此时并没有开辟B类对象的内存空间,所以并不会出现重写覆盖的现象

    System.out.println(a1.Show(b)); // A and A
    

    a1为A类对象,只能访问A类中的数据,b属于B类对象,B类为A的子类,所以向上转型,可以被A中的show(A obj)方法接受

    System.out.println(a1.Show(c)); // A and A
    

    同理,c为C类对象,拥有B父类,B父类拥有A父类,所以和第一个同理

    System.out.println(a1.Show(d)); // A and D
    

    虽然也是通过a1访问,但是传入的参数为d,show()方法的重载,选择第一个show(D obj)方法

    在这里插入图片描述

  • 对于对象a2

    它属于A类数据类型的B类对象,也就是多态,创建时B类为A类的子类,创建子类对象之前要创建父类对象,所以会为A类、B类对象都开辟内存空间。因为a2的数据类型为A类数据类型,所以只能访问A类中的数据,但是同时开辟了B类的内存空间,所以B类中如果有对A类方法的重写,则调用B中的重写方法

    System.out.println(a2.Show(b)); // B and A
    

    a2为数据类型为A的B类对象,创建子类对象时先创建父类对象,创建时分别为A类、B类开辟空间,然后因为是A类数据类型,所以应该访问A类中的show(A obj)方法,但是因为中对方法有重写,所以访问B类中的show(A obj)

    System.out.println(a2.Show(c)); // B and A
    

    同理,c为C类对象,但是向上转型,可以被show(A obj)接受

    System.out.println(a2.Show(d)); // A and D
    

    同理,但是传入的参数为d,由于方法重载,所以访问show(D obj)

    在这里插入图片描述

  • 对于对象b

    它属于B类对象,B类是A类的子类,创建子类对象之前先创建父类对象,所以在创建对象b时,会先为A类对象开辟内存空间,再开辟B类对象空间。对象b可以访问A类和B类中的方法,如果B类中存在方法重写,那么访问B类中的重写方法

    System.out.println(b.Show(b)); // B and A
    

    b为B类对象,访问B类中的Show(A obj),这里存在向上转型的情况,从下往上匹配,Object类属于所有类的父类,所以先匹配A类参数,所以访问Show(A obj)

    System.out.println(b.Show(c)); // B and A
    

    b为B类对象,传入c对象,由于方法重写以及向上转型访问B类中的show(A obj)

    System.out.println(b.Show(d)); // A and D
    

    b为B类对象,创建子类对象时先创建父类对象,访问A类中的show(D obj)

    在这里插入图片描述

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

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

相关文章

从零到一,我的AI绘画赚钱之旅:准大一新生暑假自学成才,月入学费不是梦!

大家好,我是即将步入大学校园的准大一新生。在这个漫长的暑假里,我决定学习一门新技术,充实自己。在一次网上冲浪的过程中,我偶然发现了AI绘画这个神奇的世界。以下是我在暑假期间学习AI绘画的经历,以及我是如何通过它…

缓存之Tair

介绍 ​ 在Tair出现之前的很长一段时间里,像redis、memcache这些知名NoSql数据库是不支持分布式的,在这样的背景下,由淘宝网自主开发并在2010.6开源的一个高性能、高扩展、高可靠分布式缓存,类似map的key/value结构,在…

C#实现数据采集系统-数据反写(3)ModbusTcp写入数据模块开发

写入报文分析 ModbusTcp报文详细解析见 ModbusTCP协议报文解析 写入常用的四个功能码,线圈 05,15(0x0F),寄存器06,16(0x10) 详细报文如下: //00 01 00 00 00 06 FF 05 00 01 FF 00 写单个线圈 //00 01 …

【人工智能】AI虚拟主播制作初体验:生成数字人到视频创作全流程

文章目录 💯AI虚拟主播💯使用AI绘画工具生成数字人借助GPT生成数字人所需的提示词方案一:使用Midjourney生成数字人方案二:使用TensAI生成数字人补充方案三:在D-ID内直接生成数字人 💯使用D-ID生成数字人视…

CS1.5快捷键

《黑神话悟空》玩不起,玩起了23年前的cs1.5 B11:USP(警察自带手枪) B12:Glock18(匪徒自带手枪) B13:Desert Eagle(沙漠之鹰) B14:P-228 B15:Dual Berettas(匪…

git命令大全(git checkout ,git merge,git branch,git cherry-pick)

git stash 和git commit区别git文件状态命令手册git init git clone提交和修改git log远程仓库操作 git pull git push创建分支(增删改查)git checkout ,git branch ,git mergegit loggit taggit add, git stash ,git rebase,git cherry-pick git stash …

AI绘画SD三分钟入门教程!秋叶大佬8月最新的Stable Diffusion整合包V4.9来了,完整安装部署教程奉上,附各种模型插件一次性用爽!

大家好,我是画画的小强 前几天8月15日,国内AI绘画工具开源大佬更新了StableDiffusion整合包最新版本4.9,相关信息从图中能看到,本次更新后SD WebUI已经能够支持最新的AI绘画大模型SD3.0,以及更新了SD最强的控制插件Co…

nvm 安装老的node,npm版本

1、今天想安装一个老的node与npm版本,但出现问题,安装不了 2、后来修改settings.txt文件增加如下: node_mirror: https://npmmirror.com/mirrors/node/ npm_mirror: https://npmmirror.com/mirrors/npm/ 否则因为现在访问https://nodejs.or…

Jmeter 性能测试实战教程

一、性能测试流程 进行性能测试前,我们首先需要了解一下性能测试大致分为哪些流程,这样才能保证测试过程有序开展: 1、性能需求分析 了解哪些业务需要(一般都是用户量大的核心业务,比如登录,查询等功能&…

HTML5休闲小游戏《切割大师》源码,引流、刷广告利器

HTML5休闲小游戏《切割大师》源码,直接把源码上传到服务器就能使用了! 下载链接:https://www.huzhan.com/code/goods467910.html

webpack--webpack的启用

1、创建项目目录结构 2、安装依赖 2.1 初始化项目 npm init -y 2.2 安装webpack和webpack-cli npm i webpack webpack-cli -D 2.3 打包 npx webpack ./src/main.js --modedevelopment “./src/main.js”是指定需要打包的文件 --mode是指定打包的环境--mode有两个值,…

【vue3|第27期】Vue Router 中的 Meta 属性:灵活控制与增强你的应用

日期:2024年8月23日 作者:Commas 签名:(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释:如果您觉在这里插入代码片得有所帮助,帮忙点个赞,也可以关注我,我们一起成长;如果有不…

Python优化算法11——螳螂优化算法(GOA)

科研里面优化算法都用的多,尤其是各种动物园里面的智能仿生优化算法,但是目前都是MATLAB的代码多,python几乎没有什么包,这次把优化算法系列的代码都从底层手写开始。 需要看以前的优化算法文章可以参考:Python优化算…

销售易CRM怎么样?如何自动同步?

销售易CRM是什么? 销售易CRM是一款企业级CRM软件,它利用先进的移动互联、社交网络和云计算技术,提供从营销、销售到服务的一体化解决方案。销售易CRM不仅是一个软件工具,更是一种企业经营管理理念,通过智能技术的应用…

【Hot100】LeetCode—105. 从前序与中序遍历序列构造二叉树

目录 1- 思路递归 2- 实现⭐105. 从前序与中序遍历序列构造二叉树——题解思路 3- ACM 实现 原题连接:105. 从前序与中序遍历序列构造二叉树 1- 思路 递归 前序:中左右中序:左中右 让前序的第一个元素作为中序的分割点 分割思路 1- 递归…

推荐一个java低代码开发平台-橙单

文章目录 前言一、项目介绍二、技术选型三、项目特点四、基础功能介绍五、源码下载六、官方文档总结 前言 大家好,今天为大家推荐一个开箱即用,快速开发的低代码平台。项目采用 Boot3 Flowable7 Sa-Token Vue3技术栈。 一、项目介绍 橙单中台化低代…

如何使用ssm实现基于SSM框架云趣科技客户管理系统

TOC ssm079基于SSM框架云趣科技客户管理系统jsp 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大,随着当前时代的信息化,科学化发展,让社会各行业领域都争相使用新的信息技术,对行业内的各种相关数据进行科学化&#xff…

Android compose OutlinedTextField 点击事件

点击 OutlinedTextField 响应点击事件 再OutlinedTextField外层包裹ExposedDropdownMenuBox,重要的是让点击事件关联 readOnly true,Modifier.menuAnchor()

[CLIP-VIT-L + Qwen] 多模态大模型源码阅读 - MultiModal篇

[CLIP-VIT-L Qwen] 多模态大模型源码阅读 - MultiModal篇 前情提要源码阅读导包逐行讲解 dataclass部分整体含义逐行解读 模型微调整体含义逐行解读 MultiModal类整体含义逐行解读 参考repo:WatchTower-Liu/VLM-learning; url: VLLM-BASE 前情提要 有关多模态大模型架构中的…

机器学习预处理

一、数据读取 数据的读取方式有多种,最终我们可以转化为numpy和pandas形式储存,方便后续的模型建立。 1.1 读取库的安装 需要用到的三个库 pip install pandas pip install numpy pip install openpyxl 1.2 库的使用 import pandas as pd ​ #### 1…