「JavaSE」类和对象3

news2024/11/18 13:56:24

🎇个人主页:Ice_Sugar_7
🎇所属专栏:快来卷Java啦
🎇欢迎点赞收藏加关注哦!

类和对象3

  • 🍉多态
    • 🍌重写
    • 🍌向上转型&向下转型
    • 🍌静态绑定&动态绑定
    • 🍌多态的利弊
  • 🍉写在最后

🍉多态

概念:对于同一个行为,不同的对象去做,会产生不同的状态
比如对于吃这个行为,狗这个对象去做的话就是吃狗粮;猫去做的话就是吃猫粮
再比如,对于景区买票这个行为,学生去做的话就是买学生票;儿童去做的话就是买儿童票;成人去做的话就是买成人票

java中的多态指同一个方法可以根据接收的不同参数类型,产生不同的行为
要实现多态,必须同时满足以下几个条件:

  • 子类必须要对父类中方法进行重写
  • 必须在继承体系下实现向上转型
  • 通过父类的引用调用重写的方法

下面对这些条件一一讲解

🍌重写

继承关系上,如果满足:

  • 方法名一样
  • 方法的参数列表一样

那我们就说这两个方法之间的关系是重写
举个例子:

public class Animal {
   public String name;
   public int age;
   public void eat() {
       System.out.println(name+"正在吃饭");
   }
}

public class Dog extends Animal{
   public String color;
   @Override
   public void eat() {
       System.out.println(name+"在吃狗粮");
   }
}

父类中有一个eat方法,而子类中也有一个,不同点在于它们所吃的东西不同(一个吃饭、一个吃狗粮)

重写的规则:

  • 被重写的父类方法不能被private、final修饰,并且不是构造方法、静态方法
  • 被重写的方法返回值类型可以不同,但必须具有父子关系
  • 子类方法的访问权限不能低于父类中被重写方法的访问权限。比如父类方法被public修饰,那子类中重写的方法就不能声明为 protected
  • 重写的方法可以使用 @Override 注解来显式指定,它能帮我们进行校验,确保顺利重写

重写和重载的区别:
在这里插入图片描述

🍌向上转型&向下转型

一、向上转型
创建一个子类对象,但是用父类引用来引用它
语法格式:父类类型 对象名 = new 子类类型()

Animal animal = new Cat("Mimi",1);

Animal是父类类型,但可以引用一个子类对象,因为是从小范围大范围的转换(子类是小范围,父类是大范围,这就类似隐式类型转换),安全性很好

常见的可以发生向上转型的场景:

  1. 直接赋值
    这个就是刚才上面所举的例子

  2. 方法传参
    形参为父类引用,可以接收任意子类对象

public static void eat(Animal a){
	a.eat();
}

public static void main(String[] args) {
	Cat cat = new Cat("Mimi",1);
	eat(cat);
}
  1. 作为返回值返回
    方法的返回类型为父类类型,返回任意子类对象
public Animal func() {
    Dog dog = new Dog();
    return dog;
}

向上转型可以提高代码的灵活性、通用性比如说有一个方法的参数类型是Animal类,那它就可以接收Dog类、Cat类、Bird类等实参,而且根据传递的对象的类型,确定要使用哪个对象的具体表现(比如传Dog类就表现出跑的动作,而传Bird类就表现出飞的动作),这就是我们所讲的多态

二、向下转型
将一个子类对象向上转型之后,它不能调用子类特有的属性、方法,但有时候可能需要调用子类特有的方法,所以将父类引用再还原为子类对象即可,即向下转型
简而言之就是:父类强制类型转换之后给子类。从谁转型上来的,就转下去成为谁

但是向下转型不太安全,因为需要进行强制类型转换,如果转换后的类型与向上转型之前子类对象类型不一致的话,运行时就会抛异常
举个例子,比如我想让狗喵喵叫,这肯定是不行的

    public static void main(String[] args) {
        Animal animal = new Cat();
        Animal animal1 = new Dog();
        Dog dog = new Dog();
        dog = (Dog)animal1;  //向下转型成功
        dog = (Cat)animal;    //转换失败,因为animal不是由Cat类型向上转型得到的
        dog.mew();
    }

为了防止报错,可以在向下转型之前使用关键字instanceof进行检验
o1 instanceof o2
instanceof可以用来判断o1是否是o2或者o2子类实例化的对象,如果是,返回true;反之返回false

而对于第三个条件:通过父类的引用调用重写的方法。其实你会发现只要满足前面两个条件,那第三个条件肯定也满足了
满足三个条件之后,就会发生动态绑定,它是多态的基础。而有动态绑定,那自然也有静态绑定,下面对这两个概念进行解析

🍌静态绑定&动态绑定

  1. 静态绑定

编译阶段就确定要调用哪个函数

    int add(int x,int y) {
        return x+y;
    }
    int add(int x,int y,int z) {
        return x+y+z;
    }

比如上面两个add方法构成重载,在编译阶段根据所传参数个数就能确定要调用哪个add方法

  1. 动态绑定
    当一个父类的引用指向一个子类的对象时,可以通过父类的引用调用子类重写的方法。这种情况下,Java会根据对象的实际类型来决定调用哪个方法,这就是动态绑定

动态绑定是在程序运行期间才确定要调用哪个方法

    public static void main(String[] args) {
        Animal animal = new Dog("圆圆",19);
        animal.eat();
    }

在这里插入图片描述
汇编代码观察结果

当调用一个方法时,编译器会根据引用的类型来确定要调用的方法,所以在编译阶段,调用的还是Animal的eat方法(通过汇编可以观察到)
但是程序运行时,实际上被调用的方法是由引用所指向的对象的类型决定的所以我们看到运行结果是调用Dog的eat方法

🍌多态的利弊

多态的好处:

  • 能够简化代码,避免使用大量的 if - else
    比如要写一个类来打印不同的图案(○、△、❀),如果不基于多态,实现的代码如下:
public class Shape {
    public Shape shape;
    public void draw() {
        System.out.println("画一个图形");
    }
}

public class Circle extends Shape{
    @Override
    public void draw() {
        System.out.println("○");
    }
}

public class Triangle extends Shape{
    @Override
    public void draw() {
        System.out.println("△");
    }
}

public class Flower extends Shape{
    @Override
    public void draw() {
        System.out.println("❀");
    }
}

    public static void main(String[] args) {
        String[] array = {"Triangle","Circle","Circle","Flower"};
        for(String shape:array) {
            if(shape.equals("Triangle")) {
                System.out.println("△");
            } else if(shape.equals("Circle"))  {
                System.out.println("○");
            } else if (shape.equals("Flower")) {
                System.out.println("❀");
            }
        }
    }

如果使用多态,就可以简化为:

public class Shape {
    public Shape shape;
    public void draw() {
        System.out.println("画一个图形");
    }
}

public class Circle extends Shape{
    @Override
    public void draw() {
        System.out.println("○");
    }
}

public class Triangle extends Shape{
    @Override
    public void draw() {
        System.out.println("△");
    }
}

public class Flower extends Shape{
    @Override
    public void draw() {
        System.out.println("❀");
    }
}

public static void main(String[] args) {
    Shape[] array = {new Triangle(),new Circle(),new Circle(),new Flower()};
    for(Shape shape:array) {
        shape.draw();
    }
}

以子类对象为数组元素,通过for循环调用draw函数打印相应的图案
在这里插入图片描述

  • 可扩展能力更强
    以上面打印图案为例,如果要新增一种新的形状,使用多态的方式代码改动成本也比较低

缺陷:

  • 属性没有多态性
    当父类和子类都有同名属性的时候,通过父类引用,只能引用父类自己的成员属性
  • 构造方法没有多态性
    注意:不要在构造方法里面调用重写的方法!!!因为会发生动态绑定,调用子类重写的方法,但此时子类还没构造完成,可能会出现一些极难被发现的问题

🍉写在最后

以上就是本篇文章的全部内容,如果你觉得本文对你有所帮助的话,那不妨点个小小的赞哦!(比心)

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

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

相关文章

Docker 安装 CentOS

Docker 安装 CentOS CentOS(Community Enterprise Operating System)是 Linux 发行版之一,它是来自于 Red Hat Enterprise Linux(RHEL) 依照开放源代码规定发布的源代码所编译而成。由于出自同样的源代码,因此有些要求高度稳定性…

【Docker】在centos中安装nginx

🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是平顶山大师,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的博客专栏《【Docker】安装nginx》。🎯&#…

16.云原生之kubesphere组件安装卸载

云原生专栏大纲 文章目录 KubeSphere组件介绍KubeSphere组件安装卸载配置内容参考安装组件步骤卸载组件步骤 KubeSphere组件介绍 KubeSphere 的全部可插拔组件如下: 配置项功能组件描述alertingKubeSphere 告警系统可以为工作负载和节点自定义告警策略。告警策略…

WordPress后台底部版权信息“感谢使用 WordPress 进行创作”和版本号怎么修改或删除?

不知道各位WordPress站长在后台操作时,是否有注意到每一个页面底部左侧都有一个“感谢使用 WordPress 进行创作。”,其中WordPress还是带有nofollow标签的链接;而页面底部右侧都有一个WordPress版本号,如下图中的“6.4.2 版本”。…

海盗王NPC出售物品解析器

在编辑或者查看NPC出售物品的时候,需要了解它到底出售了那些物品。 当物品很多的时候,就很难一个一个地去查了。 想到之前有做过一个物品编辑器,于是就想在那个基础上再增加一个NPC物品分析器功能。 实现如下: 将NPC的出售列表直接…

【算法Hot100系列】跳跃游戏

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…

三层架构——工业控制领域简单理解

前言闲话 工业领域对好滴软件架构的需求不高,但不意味着可以用纯面向过程式编程解决问题,这样后期维护必将大乱。 曾经和一位从业30年的老电气工程师交流工业控制编程: 我问:为啥富士康这些大厂以前的机器都不联网?&…

Gin 框架之Cookie与Session

文章目录 一、Cookie和Session的由来二、Cookie简介1. 什么是Cookie2. Cookie规范3. 安全性4. Cookie 关键配置 三、Session简介1. 什么是Session2. Session 安全性3. 如何让客户端携带 sess_id 四、使用 Gin 的 Session 插件4.1 介绍4.2 基本使用 五、 session与store5.1 会话…

第六回 花和尚倒拔垂杨柳 豹子头误入白虎堂-安装服务器管理面板AMH和cyberpanel

且说鲁智深踏入菜园之时,二三十个泼皮无赖正聚集于此,他们手持果盒酒礼,脸上嬉皮笑脸,口称前来庆贺。然而,当这群人走到粪窖边缘,打头阵的张三和李四竟妄想搬动鲁智深,结果却被他轻描淡写地一脚…

Microsoft365管理员创建共享邮箱

​​​​​​ 创建共享邮箱 项目2023/08/2110 个参与者 反馈 本文内容 创建共享邮箱并添加成员您应使用哪些权限?阻止登录共享邮箱帐户向 Outlook 添加共享邮箱 显示另外 3 个 备注 如果你的组织使用的是混合 Exchange 环境,则你应使用本地 Excha…

新能源汽车智慧充电桩方案:智能高效的充电桩管理模式及应用场景

一、行业背景 随着全球对环境保护的日益重视,新能源汽车成为了未来的发展趋势。而充电桩作为新能源汽车的核心基础设施,其智慧化的解决方案对于推动新能源汽车的普及和发展至关重要。通过智能化、高效化的充电服务,提高用户体验,…

智慧充电桩的市场前景未来

随着电动汽车的日益普及&#xff0c;充电问题成为广大车主的关注焦点。作为领先的科技企业&#xff0c;天津通捷创科为您带来了一站式解决方案——共享充电桩APP。 <h1>一、即刻定位&#xff0c;充电桩触手可及</h1> 在天津通捷创科的共享充电桩APP中&#xff0c…

洛谷P5731 【深基5.习6】蛇形方阵(C语言)

思路感觉还是比较好想的。 从 1 到 n 依次算。先往右&#xff0c;走到头往下&#xff0c;再走到头往左&#xff0c;以此类推。 #include<stdio.h>int main() {int n, i, j, k1,t0;scanf("%d", &n);int a[100][100];if (n % 2 0)t n / 2;elset n / 2 …

测温传感器表带式ATE200安装指导

ATE200 安装方法 ATE200 表带式无线测温传感器适用于断路器动触头、静触头、电缆接头、母排等处。 表带式无线温度传感器结构说明: ATE200 structure introduction: 1 —— 无线温度传感器主体&#xff0c;测温探头在背面 The core of wireless temperature sensor ATE200,…

2023总结,瞳孔滤镜

2022总结&#xff0c;强风吹拂 2021总结&#xff0c;欲望反光 2020总结&#xff0c;我与思阳 2019总结&#xff0c;乘风破浪 2018总结&#xff0c;蜗行牛步 2017总结&#xff0c;勿忘初心 得益于疫情的结束&#xff0c;出行自由&#xff0c;2023年09月24日下午 &#xf…

Qt/C++自定义界面大全/20套精美皮肤/26套精美UI界面/一键换肤/自定义颜色/各种导航界面

一、前言 这个系列对应自定义控件大全&#xff0c;一个专注于控件的编写&#xff0c;一个专注于UI界面的编写&#xff0c;程序员有两大软肋&#xff0c;一个是忌讳别人说自己的程序很烂很多bug&#xff0c;一个就是不擅长UI&#xff0c;基本上配色就直接rgb&#xff0c;对于第…

精品基于Uniapp+springboot校园学校趣事管理系统app

《[含文档PPT源码等]精品基于Uniappspringboot趣事管理系统app》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; 开发语言&#xff1a;Java 后台框架&#xff1a;springboot、ssm 安卓…

大模型学习与实践笔记(九)

一、LMDeply方式部署 使用 LMDeploy 以本地对话方式部署 InternLM-Chat-7B 模型&#xff0c;生成 300 字的小故事 2.api 方式部署 运行 结果&#xff1a; 显存占用&#xff1a; 二、报错与解决方案 在使用命令&#xff0c;对lmdeploy 进行源码安装是时&#xff0c;报错 1.源…

航空飞行器运维VR模拟互动教学更直观有趣

传统的二手车鉴定评估培训模式存在实践性不强、教学样本不足、与实际脱节等一些固有的不足。有了VR虚拟仿真技术的加持&#xff0c;二手车鉴定评估VR虚拟仿真实训系统逐渐进入实训领域&#xff0c;为院校及企业二手车检测培训提供了全新的解决方案。 高职院校汽车专业虚拟仿真实…

MySQL 基于创建时间进行RANGE分区

MySQL是一款广泛使用的关系型数据库。在MySQL中&#xff0c;大量数据场景提高查询效率是非常关键的&#xff0c;所以&#xff0c;对数据表进行分区是一个很好的选择。 在创建分区表之前&#xff0c;需要了解一下MySQL分区的基本概念。MySQL分区可以将一个大表分成多个小表&…