【JavaSE】多态(多态实现的条件 重写 向上转移和向下转型 向上转型 向下转型 多态的优缺点 避免在构造方法种调用重写的方法)

news2025/2/26 2:34:48

文章目录

  • 多态
    • 多态实现的条件
    • 重写
    • 向上转移和向下转型
      • 向上转型
      • 向下转型
    • 多态的优缺点
    • 避免在构造方法种调用重写的方法


多态

一种事物,多种形态。
多态的概念:去完成某个行为,当不同对象去完成时会产生出不同的状态。

多态实现的条件

1.必须再继承体系下。
2.子类必须要对父类中的方法进行重写。
3.通过父类的引用调用重写的方法。

在这里插入图片描述

当我们发生向上转型之后,此时通过父类引用只能访问父类自己的成员,不能访问到子类特有的成员。

重写

重写需要满足三个条件:

  1. 方法名称相同。
  2. 参数列表相同。
  3. 返回值相同。
class Animal{
    public String name;
    public int age;

    public void eat(){
        System.out.println(name+" 正在吃饭!");
    }
}
class Dog extends Animal{
    public void wangwang(){
        System.out.println(name+" 正在汪汪叫!");
    }
    @Override
    public void eat(){
        System.out.println(name+" 正在吃狗粮!");
    }
}

在这里插入图片描述
编译器可以生成:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

class Animal{
    public String name;
    public int age;

    public void eat(){
        System.out.println(name+" 正在吃饭!");
    }
}
class Dog extends Animal{
    public void wangwang(){
        System.out.println(name+" 正在汪汪叫!");
    }
    @Override
    public void eat(){
        System.out.println(name+" 正在吃狗粮!");
    }
}
class Bird extends Animal{
    public String wing;//翅膀
    public void fly(){
        System.out.println(name+" 正在飞!");
    }
    @Override
    public void eat(){
        System.out.println(name+" 正在吃鸟粮!");
    }
}
public static void main(String[] args) {
       Animal animal1 = new Dog();
       animal1.name = "小黄";
       animal1.eat();
	System.out.println("=================");
       Animal animal2 = new Bird();
       animal2.name = "圆圆";
       animal2.eat();
}

在这里插入图片描述
静态绑定:也称为前期绑定(早绑定),即在编译时,根据用户所传递实参类型就确定了具体调用那个方法。典型代表函数重载。
动态绑定:也称为后期绑定(晚绑定),即在编译时,不能确定方法的行为,需要等到程序运行时,才能够确定具体调用那个类的方法。

在这里插入图片描述

重写需要注意:

  1. private修饰的方法不能被重写。
  2. static修饰的方法不能被重写。
  3. 子类的访问修饰限定权限要大于等于父类的权限。 private < 默认 < protected < public
  4. 被final修饰的方法不能被重写,此时这个方法被称作密封方法。
    在这里插入图片描述

向上转移和向下转型

向上转型

实际就是创建一个子类对象,将其当成父类对象来使用。

  1. 直接赋值
class Animal{
    public String name;
    public int age;

    public void eat(){
        System.out.println(name+" 正在吃饭!");
    }
}
class Dog extends Animal{
    public void wangwang(){
        System.out.println(name+" 正在汪汪叫!");
    }
}
public class Test2 {
    public static void main1(String[] args) {
        Dog dog = new Dog();
        dog.name = "小黄";
        dog.eat();
        dog.wangwang();
        Animal animal = dog;
    }
}
  1. 方法传参
class Animal{
    public String name;
    public int age;

    public void eat(){
        System.out.println(name+" 正在吃饭!");
    }
}
class Dog extends Animal{
    public void wangwang(){
        System.out.println(name+" 正在汪汪叫!");
    }
}
public class Test2 {
    public static void func(Animal animal){
    }
    public static void main(String[] args) {
        Dog dog = new Dog();
        func(dog);
    }
}

3.方法返回值

class Animal{
    public String name;
    public int age;

    public void eat(){
        System.out.println(name+" 正在吃饭!");
    }
}
class Dog extends Animal{
    public void wangwang(){
        System.out.println(name+" 正在汪汪叫!");
    }
}
public class Test2 {
    public static Animal func2(){
        return new Dog();
    }
    public static void main(String[] args) {
        func2();
    }
}

优点:让代码实现更简单灵活。
缺陷:不能调用到子类特有的方法。

向下转型

class Animal{
    public String name;
    public int age;

    public void eat(){
        System.out.println(name+" 正在吃饭!");
    }
}
class Dog extends Animal{
    public void wangwang(){
        System.out.println(name+" 正在汪汪叫!");
    }
}
public class Test2 {
    public static void main(String[] args) {
        Animal animal1 = new Dog();
        //向下转型
        Dog dog = (Dog)animal1;
        dog.name = "小黄";
        dog.wangwang();
    }
}

向下转型非常不安全,比如:
在这里插入图片描述

解决方法:Java中为了提高向下转型的安全性,引入了 instanceof ,如果该表达式为true,则可以安全转换。

if(animal1 instanceof Dog){
     //向下转型
     Dog dog = (Dog)animal1;
     dog.name = "小黄";
     dog.wangwang();
}

可以理解为判断animal1这个引用,是不是引用Dog对象。

多态的优缺点

class Shap{
    public  void draw(){
        System.out.println("画图形!");
    }
}
class Rect extends Shap{
    @Override
    public void draw() {
        System.out.println("画矩形!");
    }
}
class Cycle extends Shap{
    @Override
    public void draw() {
        System.out.println("画圆!");
    }
}
class Flower extends Shap{
    @Override
    public void draw() {
        System.out.println("画一朵花❀!");
    }
}
public class Test3 {
    public static void drawMap(Shap shap){
        shap.draw();
    }
    public static void main(String[] args) {
        Rect rect = new Rect();
        Cycle cycle = new Cycle();

        drawMap(rect);
        drawMap(cycle);
        drawMap(new Flower());
    }
}

在这里插入图片描述

class Shap{
    public  void draw(){
        System.out.println("画图形!");
    }
}
class Rect extends Shap{
    @Override
    public void draw() {
        System.out.println("画矩形!");
    }
}
class Cycle extends Shap{
    @Override
    public void draw() {
        System.out.println("画圆!");
    }
}
class Flower extends Shap{
    @Override
    public void draw() {
        System.out.println("画一朵花❀!");
    }
}
public class Test3 {
    public static void drawMap2(){
        Rect rect = new Rect();
        Cycle cycle = new Cycle();
        Flower flower = new Flower();
        //c r c r f
        String[] shapes = {"cycle", "rect", "cycle", "rect", "flower"};
        for (String shape : shapes) {
            if (shape.equals("cycle")) {
                cycle.draw();
            } else if (shape.equals("rect")) {
                rect.draw();
            } else if (shape.equals("flower")) {
                flower.draw();
            }
        }
    }
    public static void main(String[] args) {
        drawMap2();
    }
}

在这里插入图片描述

多态实现:

public static void drawMap3(){
  Rect rect = new Rect();
  Cycle cycle = new Cycle();
  Flower flower = new Flower();
  Shap [] shaps = {cycle,rect,cycle,rect,flower};
  for(Shap shap:shaps){
      shap.draw();
  }
}

多态好处:

  1. 能够降低代码的 “圈复杂度”, 避免使用大量的 if - else。
  2. 可扩展能力更强如果要新增一种新的形状, 使用多态的方式代码改动成本也比较低。

多态缺陷:代码的运行效率降低。

  1. 属性没有多态性:当父类和子类都有同名属性的时候,通过父类引用,只能引用父类自己的成员属性。
  2. 构造方法没有多态性。

避免在构造方法种调用重写的方法

下面我们看一段有坑的代码:

class B {
    public B() {
// do nothing
        func();
    }
    public void func() {
        System.out.println("B.func()");
    }
}
class D extends B {
    private int num = 1;
    @Override
    public void func() {
        System.out.println("D.func() " + num);
    }
}
public class Test4 {
    public static void main(String[] args) {
        D d = new D();
    }
}

当在父类的构造方法当中去调用父类和子类重写的方法的时候,此时会调用子类的。
num为0是因为父类此时还没有走完,就来到了打印阶段。

在这里插入图片描述
结论: “用尽量简单的方式使对象进入可工作状态”, 尽量不要在构造器中调用方法(如果这个方法被子类重写, 就会触发动态绑定, 但是此时子类对象还没构造完成), 可能会出现一些隐藏的但是又极难发现的问题。

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

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

相关文章

路径规划算法:基于被囊群优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于被囊群优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于被囊群优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法…

python 读写csv文件方法

csv是一种结构化文件&#xff0c;可以将文本转化成矩阵的形式&#xff0c;方便程序读取和处理。下面来介绍一下使用 python读写 csv文件的方法&#xff1a; 1.首先需要使用 pip安装 python包&#xff0c;然后将 csv文件解压到一个文件夹下 2.使用 pip安装 python包&#xff0c;…

(2)设置飞机进行调优

文章目录 前言 2.1 电池设置 2.2 电机设置 2.3 PID控制器初始设置 前言 以下参数应根据你的飞机的规格正确设置。每一个都会影响调优过程的质量。 2.1 电池设置 确保你的 VTOL 电机的推力曲线尽可能的线性是非常重要的。一个线性的推力曲线意味着电机产生的实际推力的变化…

uniapp学习日记之request自定义请求头

uniapp学习日记之request自定义请求头 在学习uniapp的过程中&#xff0c;由于笔者是从Vue项目转来学习uniapp&#xff0c;在使用uni.request时&#xff0c;发现在浏览器调试时&#xff0c;无法在请求头header中添加token字段&#xff0c;愤而弃之&#xff0c;便开始使用axios组…

python条件循环

python条件循环 Python中的条件循环&#xff0c;可以用来解决很多问题&#xff0c;比如计算一组数据中的最大值&#xff0c;或者从列表中获取一个元素。这里就以条件循环为例来介绍下吧。 Python的条件循环可以分为两种&#xff0c;一种是直接使用 for循环来计算最大值&#xf…

Nvidia技术路线和卷积神经网络介绍

1.Nvidia技术路线概述 2.卷积神经网络介绍 软硬件平台 目的:用卷积神经网络(CNNs)将车前部摄像头捕捉到的原始像素图映射为汽车的方向操控命令。 训练:这套端到端学习系统使用了NVIDIA DevBox, 用Torch 7进行训练。 操作:一台 NVIDIA DRIVE PX 自动驾驶汽车计算…

Mathtype修改硕士论文格式

Mathtype修改硕士论文格式 1将word格式的公式变为mathtype格式1选中公式2点击mathtype中的转换公式 2修改mathtype格式的公式文字版式 1将word格式的公式变为mathtype格式 1选中公式 如果不选公式默认全文所有公式或者指定的公式。 2点击mathtype中的转换公式 选择要转换的…

QML画布绘制(Canvas Paint)

目录 一 QML介绍 二 QML的使用场合 三 实例演示 一 QML介绍 QML是Qt Quick的缩写&#xff0c;它是一种新型的、面向对象的、跨平台的脚本语言&#xff0c;可以用来描述用户界面或应用程序的交互逻辑。QML可以在Qt应用程序中使用&#xff0c;也可以在其他JavaScript应用程序中…

freertos-简介(一)

FreeRTOS 裸机 不带任何操作系统 只能先打完游戏回复信息 实时性差&#xff0c;程序轮流执行delay空等待&#xff0c;CPU不执行其他代码结构臃肿&#xff0c;实现功能都在while循环 RTOS 实时操作系统 会执行打游戏一个时间片再回复信息一个时间片交替执行 在宏观下人类不…

全网最详细部署配置中科大chatgpt学术优化环境

目录 前期准备工作修改config_private.py文件创建私钥配置代理网络的地址 前期准备工作 项目地址: https://github.com/binary-husky/gpt_academic 使用git下载到本地 git clone https://github.com/binary-husky/gpt_academic.git使用conda创建虚拟环境chatgpt-academic …

Grafana系列-统一展示-8-ElasticSearch日志快速搜索仪表板

系列文章 Grafana 系列文章 概述 我们是基于这篇文章: Grafana 系列文章&#xff08;十二&#xff09;&#xff1a;如何使用 Loki 创建一个用于搜索日志的 Grafana 仪表板, 创建一个类似的, 但是基于 ElasticSearch 的日志快速搜索仪表板. 最终完整效果如下: &#x1f4dd;…

近世代数 笔记与题型连载 第十二章(同态与同构)

文章目录 基本概念同构的概念和性质同态与同构凯莱定理自同态和自同构同态核 相关题型1.证明两个代数系统是同态的2.判断同态的类型&#xff08;满同态、单一同态和同构&#xff09;3.对于指定的有限群&#xff0c;找出其对应同构的置换群4.证明某个映射是同构映射5.求指定的同…

【Chrome】最简单方法更改用户文件存储目录User Data

不知不觉C盘下面GoogleChrome已经4.5G了&#xff0c;删除只是一时为快&#xff0c;要想痛快那还是乔迁其他盘符为妙 希望大家的C盘不要过于委屈&#xff01;&#xff01;&#xff01; 关键注意点&#xff1a;网上的其他教程有个很大的错误&#xff08;误导&#xff0c;就是使用…

JVM 对象的实例化内存布局和访问定位

对象的实例化 创建对象的方式: new: 包含 xxx的静态方法&#xff0c; xxxBuilder 或 xxxFactory 的静态方法Class 的 newInstance: 反射的方式&#xff0c;只能调用空参的构造器&#xff0c;权限必须是 publicConstructor 的 newInstance(XXX): 反射方式&#xff0c;可以调用…

10分钟打造基于ChatGPT的Markdown智能文档

ChatGPT可以帮助我们实现很多原本很难实现功能&#xff0c;为传统系统加入AI支持&#xff0c;从而提升用户体验。本文介绍了如何给在线Markdown文档系统添加ChatGPT问答支持&#xff0c;将静态文档改造为智能文档。原文: Build a ChatGPT Powered Markdown Documentation in No…

第五十九章 Unity 发布Android平台

本章节我们讲解如何打包发布到安卓手机平台。要为 Android 构建和运行应用程序&#xff0c;必须安装 Unity Android Build Support 平台模块。还需要安装 Android 软件开发工具包&#xff08;SDK&#xff09;和原生开发工具包&#xff08;NDK&#xff09;才能在 Android 设备上…

【UDS】ISO15765-2之诊断时间参数

文章目录 简介分类1. P2client2. P2server3. P2*client4. P2*server5. S3client5. S3server 总结 ->返回总目录<- 简介 诊断层包含六种定时器时间参数&#xff1a;P2client, P2client, P2server, P2server, S3client, S3server。 相对来说&#xff0c;比较好理解。就是…

Unity的UGUI避免行的开头出现符号

一、遇到问题 大家好&#xff0c;我是阿赵。最近在游戏过版署的时候&#xff0c;修改意见里面有一条&#xff0c;游戏内部分文本内容中有标点符号出现在行首的问题。 一般来说&#xff0c;我们编辑文本的时候&#xff0c;是会注意不要把标点符号在换行的时候刚好出现的在行首的…

从学校到职场:在阿里的这7年

简介&#xff1a; 本文不仅希望能给一些初入职场的同学一些思考&#xff0c;也是通过自己阿里7年的总结&#xff0c;对自己未来的一种期望&#xff0c;也希望自己未来再遇到槽糕的处境迷茫的时候&#xff0c;可以回看下自己的心路历程&#xff0c;并做出更理性的选择。 引言&a…

软件测试基础知识整理(二) - 常用dos命令、服务器和域名

目录 一、常用dos命令 二、服务器和域名 2.1 网站上线的基本条件 2.1.1 域名 2.1.2 空间、服务器、云存储 一、常用dos命令 Win R 打开运行窗口&#xff0c;输入cmd即可进入命令行窗口 常用命令作用举例ipconfig/all查看IP的主机信息&#xff0c;DNS信息&#xff0c;物理…