【️如何理解Java中的多态】

news2024/9/22 19:42:42

在这里插入图片描述

✅如何理解Java中的多态?

    • ✅理解Java中的多态
  • ✅ 扩展知识仓
    • ✅方法的重载
    • ✅方法的重写
    • ✅重载和重写的区别区分

✅理解Java中的多态

多态的概念比较简单,就是同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。


如果按照这个概念来定义的话,那么多态应该是一种运行期的状态。为了实现运行期多态,或者说是动态绑定,需要满足三个条件:
  • 有类继承或者接口实现
  • 子类要重写父类的方法
  • 父类的引用指向子类的对象

简单用代码来解释一下:
public class Parent {
	public void call() {
		sout("im Parent") ;
	}
}

// 1.有类继承或者接口实现
public class Son extends Parent {
	// 2.子类要重写父类的方法
	public void call() {
		sout("im Son");
	}
}

// 1.有类继承或者接口实现
public class Daughter extends Parent {
	// 2.子类要重写父类的方法
	public void call() {
		sout("im Daughter");
	}
}

public class Test {
	public static void main(stringl] args) {
		Parent p = new Son(); //3.父类的引用指向子类的对象
		Parent p1 = new Daughter(); //3.父类的引用指向子类的对象
	}
}

这样,就实现了多态,同样是Parent类的实例,p.call 调用的是Son类的实现、p1.call调用的是Daughter的实现。


有人说,你自己定义的时候不就已经知道p是son,p1是Daughter了么。但是,有些时候你用到的对象并不都是自己声明的。
比如Spring 中的IOC出来的对象,你在使用的时候就不知道他是谁,或者说你可以不用关心他是谁。根据具体情况而定。
前面说多态是一种运行期的概念。还有一种说法,包括维基百科也说明,认为多态还分为动态多态和静态多态。
一般认为Jva中的函数重载是一种静态多态,因为他需要在编译期决定具体调用哪个方法。关于这一点,不同的人有不同的见解,建议在面试中如果被问到,可以这样回答:

     我认为,多态应该是一种运行期特性,Java中的重写是多态的体现。不过也有人提出重载是一种静态多态的想法,这个问题在StackOverflow等网站上有很多人讨论,但是并没有什么定论。我更加倾向于重载不是多态。


这样沟通,既能体现出你了解的多,又能表现出你有自己的思维,不是那种别人说什么就是什么的。

✅ 扩展知识仓

✅方法的重载

    方法的重载就是函数或者方法有同样的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者重载方法。


public class HollisExample {
	// 方法重载 - 第一个方法
	public void display(int a) {
		System.out.println("Got Integer data.");
	}

	// 方法重载 - 第二个方法
	public void display(String b) {
		System.out.println("Got String data.");
	}
}

总之,方法的重载(Overloading)是指在同一个类中,可以有多个同名方法,只要它们的参数列表不同即可。方法的重载可以是参数个数的不同,也可以是参数类型的不同。

方法的重载使得程序可以根据不同的参数列表调用同名方法,增加了程序的灵活性和可读性。


再看一段代码:
public class Calculator {  
    // 加法方法,接受两个整数参数  
    public int add(int a, int b) {  
        return a + b;  
    }  
      
    // 加法方法,接受三个整数参数  
    public int add(int a, int b, int c) {  
        return a + b + c;  
    }  
      
    // 加法方法,接受两个浮点数参数  
    public double add(double a, double b) {  
        return a + b;  
    }  
      
    // 加法方法,接受三个浮点数参数  
    public double add(double a, double b, double c) {  
        return a + b + c;  
    }  
      
    public static void main(String[] args) {  
        Calculator calculator = new Calculator();  
          
        int sum1 = calculator.add(2, 3);      // 调用第一个add方法(两个整数)  
        int sum2 = calculator.add(4, 5, 6);  // 调用第二个add方法(三个整数)  
        double sum3 = calculator.add(2.5, 3.5);  // 调用第三个add方法(两个浮点数)  
        double sum4 = calculator.add(4.5, 5.5, 6.5);  // 调用第四个add方法(三个浮点数)  
          
        System.out.println("Sum1: " + sum1);  
        System.out.println("Sum2: " + sum2);  
        System.out.println("Sum3: " + sum3);  
        System.out.println("Sum4: " + sum4);  
    }  
}

在这个例子中,创建了一个名为 Calculator 的类,其中包含了四个名为 add 的方法。这四个方法分别接受不同类型和数量的参数,实现了方法的重载。在 main 方法中,我们根据传入的参数类型和数量调用相应的 add 方法,演示了方法的重载在实际编程中的应用。

✅方法的重写

    重写指的是在Java的子类与父类中有两个名称、参数列表都相同方法的情况。由于他们具有相同的方法签名,所以子类中的新方法将覆盖父类的原有方法。

public class Parent {
	// 父类的方法
	public void display() {
		System.out.println("Parent display()");
	}
}

class Child extends Parent {
	// 子类重写了父类的方法
	@Override
	public void display() {
		System.out.println("Child display()");
	}
}

public class Main {
	public static void main(String[] args) {
		Parent objl = new Parent();
		obj1.display(); // 输出“Parent display()”


		Parent obj2 = new Child();
		obj2.display(); // 输出“Child display()”
	}
}

总之,方法的重写(Overriding)是面向对象编程中的一个重要概念,指的是在子类中重新定义父类中的方法,以覆盖(override)父类中的原有方法。重写方法的目的是为了在子类中提供特定的行为,而不必修改父类的代码。

方法的重写需要满足以下规则:

1.方法名、参数列表必须与父类中的方法完全****相同
2.返回类型可以是父类方法返回类型的子类型
3.子类方法的访问级别不能低于父类方法的访问级别

看一个代码实现方法的重写和多态的应用:

class Animal {  
    public void makeSound() {  
        System.out.println("The animal makes a sound");  
    }  
}  
  
class Dog extends Animal {  
    @Override  
    public void makeSound() {  
        System.out.println("The dog barks");  
    }  
      
    public void bark() {  
        System.out.println("The dog barks");  
    }  
}  
  
class Cat extends Animal {  
    @Override  
    public void makeSound() {  
        System.out.println("The cat meows");  
    }  
      
    public void meow() {  
        System.out.println("The cat meows");  
    }  
}  
  
class Zoo {  
    public void playWithAnimal(Animal animal) {  
        animal.makeSound();  // 调用 Animal 类的方法  
        animal.bark();  // 调用 Dog 类的方法,因为 animal 实际上是 Dog 对象  
        animal.meow();  // 调用 Cat 类的方法,因为 animal 实际上是 Cat 对象  
    }  
}  
  
public class Main {  
    public static void main(String[] args) {  
        Zoo zoo = new Zoo();  
        Animal animal1 = new Dog();  
        Animal animal2 = new Cat();  
          
        zoo.playWithAnimal(animal1);  // 输出 "The dog barks" 和 "The dog barks" 和 "The dog barks"  
        zoo.playWithAnimal(animal2);  // 输出 "The cat meows" 和 "The cat meows" 和 "The cat meows"  
    }  
}

在这个例子中,定义了一个 Animal 类,两个子类 Dog 和 Cat,以及一个 Zoo 类。Dog 类和 Cat 类分别重写了 makeSound 方法,并且添加了各自特有的方法 bark 和 meow。在 Zoo 类的 playWithAnimal 方法中,我们传入了一个 Animal 类型的参数。由于多态的存在,这个参数实际上可以是一个 Dog 对象或一个 Cat 对象。在方法内部,我们调用了 animal 的 makeSound 方法(实际上是调用子类的方法),以及子类特有的方法 bark 和 meow。因此,根据传入的参数类型,我们可以得到不同的输出结果。这个例子展示了方法的重写和多态的应用,使得程序更加灵活和可扩展。

✅重载和重写的区别区分

1、重载是一个编译期概念、重写是一个运行期概念。
2、重载遵循所谓 “编译期绑定” , 即在编译时根据参数变量的类型判定应该调用哪一个方法。
3、重写遵循所谓 “运行期绑定” , 即在运行的时候,根据引用变量所指向的实际对象的类型来调用方法。

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

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

相关文章

MT6785|MTK6785安卓核心板功能规格介绍_Helio G95核心板

MT6785安卓核心板是一款功能强大的工业级4G智能模块,它采用了Android 9.0操作系统。该核心板内置了蓝牙、FM、WLAN和GPS模块,具有高度集成的基带平台,结合了调制解调器和应用处理子系统,以支持LTE/LTE-A和C2K智能终端应用。 MTK67…

11.2 设备树下的 LED 驱动

一、修改设备树文件 首先进入该目录下 /linux/atk-mpl/linux/my_linux/linux-5.4.31/arch/arm/boot/dts 打开 stm32mp157d-atk.dts 文件,在根节点 "/" 最后输入以下内容: stm32mp1_led {compatible "atkstm32mp1-led"; // 设置…

Gobuster工具详解

目录 Gobuster工具介绍 主要特性 支持模式及全局参数列举 安装 使用 Dir模式 DNS模式 Vhost模式 fuzz模式 TFTP模式 S3、gcs模式 字典 docker运行gobuster Gobuster工具介绍 Gobuster 是一款用于在Web应用程序中进行目录和文件爆破的开源工具。它通过尝试在目标网…

【超详细】基于单片机控制的十字道路口交通灯控制

目录 最终效果 一、设计任务 二、设计报告 1 设计说明 1.1功能分析 1.1.1整体系统功能分析 1.1.2显示状态功能分析 1.1.3设置状态功能分析 1.1.4紧急状态功能分析 1.2方案比选 1.2.1车辆LED数码管倒计时显示板块 1.2.2车辆信号灯显示板块 1.2.3行人信号灯显示板块 …

JavaWeb笔记之前端开发CSS

一 、引言 1.1 CSS概念 层叠样式表(英文全称:Cascading Style Sheets)是一种用来表现HTML(标准通用标记语言的一个应用)或XML(标准通用标记语言的一个子集)等文件样式的计算机语言。CSS不仅可以静态地修饰网页&…

Open5GSUeRANSim2:对安装在同一个VM上的OPEN5GS和UERANSIM进行配置和抓取wireshark报文

参考链接: Configuring SCTP & NGAP with UERANSIM and Open5GS on a Single VM for the Open5GS & UERANSIM Series https://www.youtube.com/watch?vINgEX5L5fkE&listPLZqpS76PykwIoqMdUt6noAor7eJw83bbp&index5 Configuring RRC with UERANSI…

YOLOv5性能评估指标->mAP、Precision、Recall、FPS、Confienc (讲解论文关注的主要指标)

简介 这篇博客,主要给大家讲解我们在训练yolov5时生成的结果文件中各个图片及其中指标的含义,帮助大家更深入的理解,以及我们在评估模型时和发表论文时主要关注的参数有那些。本文通过举例训练过程中的某一时间的结果来帮助大家理解&#xf…

LeetCode:162. 寻找峰值、1901. 寻找峰值 II(二分 C++)

目录 162. 寻找峰值 题目描述: 实现代码与解析: 二分 原理思路: 1901. 寻找峰值 II 题目描述: 实现代码与解析: 二分 原理思路: 162. 寻找峰值 题目描述: 峰值元素是指其值严格大于左…

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚

目录 一、实验 1.环境 2. GitLab 共享库新建HELM CI流水线 3.Jenkins新建HELM CI流水线 5.Jenkins构建前端项目 6.GitLab 共享库新建HELM CD流水线 7.Jenkins新建HELM CD流水线 8.HELM完成前端项目应用发布与回滚 9.Jenkins再次构建前端项目 10.HELM再次完成前端项目…

在灾难推文分析场景上比较用 LoRA 微调 Roberta、Llama 2 和 Mistral 的过程及表现

引言 自然语言处理 (NLP) 领域的进展日新月异,你方唱罢我登场。因此,在实际场景中,针对特定的任务,我们经常需要对不同的语言模型进行比较,以寻找最适合的模型。本文主要比较 3 个模型: RoBERTa、Mistral-7B 及 Llama-…

HP服务器idrac设置以及系统安装

HP服务器idrac设置以及系统安装 一、设置管理口的地址和密码1、HP服务器重新界面选择"F9"进入BIOS,设置iLo5(idrac)的IP和用户名密码。2、选择"系统配置"。3、选择"iLO 4"配置程序。4、网络选项是设置idrac管理口的地址,设…

使用C语言实现文件的拷贝——底层内存分析

使用C语言实现文件的拷贝 本文主要涉及sprintf()函数的讲解以及系统IO与标准IO的区别和一个实例使用C语言实现文件的拷贝,在最后还深度刨析了文件拷贝的底层原理。 文章目录 使用C语言实现文件的拷贝一、 sprintf()函数1.1 sprintf ()函数的参…

Java版直播商城免 费 搭 建:电商、小程序、三级分销及免 费 搭 建,平台规划与营销策略全掌握

随着互联网的快速发展,越来越多的企业开始注重数字化转型,以提升自身的竞争力和运营效率。在这个背景下,鸿鹄云商SAAS云产品应运而生,为企业提供了一种简单、高效、安全的数字化解决方案。 鸿鹄云商SAAS云产品是一种基于云计算的软…

Netty Review - ObjectEncoder对象和ObjectDecoder对象解码器的使用与源码解读

文章目录 概述ObjectEncoderObjectDecoder Code源码分析ObjectEncoderObjectDecoder 小结 概述 Netty是一个高性能、异步的网络应用程序框架,它提供了对TCP、UDP和文件传输的支持。在Netty中,数据的发送和接收都是以字节流的形式进行的,因此需…

从实践角度优化数据库设计:深入解析三范式的应用

总述 第一范式(1NF):要求关系模式中的每个属性都是不可分的数据项,即属性具有原子性。第二范式(2NF):在满足1NF的基础上,要求关系模式中的所有非主属性都完全函数依赖于整个候选键(或主键)。第三范式(3NF):在满足2NF的基础上,要求关系模式中的每个非主属性都不传…

LVS最终奥义之DR直接路由模式

1 LVS-DR(直接路由模式) 1.1 LVS-DR模式工作过程 1.客户端通过VIP将访问请求报文(源IP为客户端IP,目标IP为VIP)发送到调度器 2.调度器通过调度算法选择最适合的节点服务器并重新封装数据报文(将源mac地址改为调度器的mac地址&am…

centos(linux)安装jenkins

官网:https://pkg.jenkins.io/redhat/ 安装官网进行操作: sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat/jenkins.reposudo rpm --import https://pkg.jenkins.io/redhat/jenkins.io-2023.key若出现如下错误: …

JavaScript基础函数+对象+继承

目录 1.创建函数 2.函数分类 2.1带参数函数 2.2匿名函数 2.3嵌套函数 2.4立即执行函数 ES6特有的箭头函数 2.5对象中的函数 3.this对象 4.有参构造函数创建对象 5.原型 prototype 6.函数应用(继承) 6.1原型链继承 6.2构造继承 6.3组合继承&…

Observability:捕获 Elastic Agent 和 Elasticsearch 之间的延迟

在现代 IT 基础设施的动态环境中,高效的数据收集和分析至关重要。 Elastic Agent 是 Elastic Stack 的关键组件,通过促进将数据无缝摄取到 Elasticsearch 中,在此过程中发挥着至关重要的作用。 然而,显着影响此过程整体有效性的关…

vue3使用mock模拟后端接口

安装mock axios yarn add mock yarn add axios 新建在src/mockdata/automenu.js 模拟后端的json数据格式 import Mock from mockjs Mock.mock(/menu,get,{status: 200,menuList: [{id : 1,iconCls: "fa fa-window",name: 系统管理,url: /},{id: 2,icon: icon-j…