【Java】:方法重写、动态绑定和多态

目录

一个生动形象的例子

场景设定

1. 方法重写(Method Overriding)

2. 动态绑定(Dynamic Binding)

3. 多态(Polymorphism)

归纳关系:

重写

概念

条件

重写的示例

重载与重写的区别

动态绑定

定义:

多态性的实现:

与静态绑定的区别:

示例:

多态

定义

实现方式

实现原理

应用场景

示例

意义


一个生动形象的例子

场景设定

想象一个汽车制造厂,其中有不同类型的车辆,如轿车、SUV和卡车。每种车辆都有自己独特的驾驶行为,但它们都继承自一个基本的“汽车”类。

1. 方法重写(Method Overriding)
  • 定义:子类提供与父类相同方法名、参数列表和返回值类型的方法,以覆盖父类中的方法。

在这个例子中,假设“汽车”类有一个名为“drive”的方法,它输出“汽车正在行驶”。但是,轿车、SUV和卡车在行驶时可能有不同的表现,因此它们各自重写了“drive”方法。

  • 轿车类重写“drive”方法:输出“轿车平稳行驶”。
  • SUV类重写“drive”方法:输出“SUV越野行驶”。
  • 卡车类重写“drive”方法:输出“卡车重载行驶”。
2. 动态绑定(Dynamic Binding)
  • 定义:在运行时根据对象的实际类型来确定调用哪个重写后的方法。

现在,假设制造厂有一个测试驾驶员,他只需要知道如何“驾驶”(即调用“drive”方法),而不需要知道具体是哪种车型。当他驾驶不同类型的汽车时,会动态地绑定到相应车型重写的“drive”方法上。

3. 多态(Polymorphism)
  • 定义:允许一个接口(或父类引用)引用多种实际类型,并根据实际类型执行对应的方法。

在测试中,驾驶员可以驾驶不同类型的汽车,而每种车型在行驶时展现出不同的行为,这就是多态的体现。虽然驾驶员都是通过调用“drive”方法来驾驶汽车,但具体的行驶表现却因车型的不同而不同。

归纳关系:
  • 方法重写是实现多态的基础,子类通过重写父类的方法以提供自己独特的行为。
  • 动态绑定则使得在运行时能够根据实际对象的类型来调用相应重写后的方法,从而实现多态的效果。
  • 多态则是这些技术综合应用的结果,它允许我们使用统一的接口(如本例中的“drive”方法)来处理不同类型的对象,并在运行时展现出各自独特的行为。

重写

概念

方法重写,是面向对象编程中的一个重要概念,特别是在Java这样的面向对象的编程语言中。方法重写允许子类提供一个与父类中已有方法具有相同方法签名(即方法名和参数列表相同)的实现。

通过方法的重写,子类可以改变或扩展从父类继承的方法的行为。


条件

在Java中,要进行方法重写,必须满足以下条件:

  • 方法名和参数列表必须与父类中被重写的方法相同:

这是为了确保在运行时能够正确地识别和调用重写的方法。

  • 访问修饰符不能低于父类方法的访问修饰符:

例如,如果父类方法时 public 的,那么重写该方法的方法也必须时 public 的。

  • 返回类型必须与父类中被重写的方法的返回类型相同
  • 子类方法抛出的异常类型必须是父类方法所抛出异常类型的子集:

子类方法可以不抛出异常,或者抛出与父类方法相同的异常或其子类型的异常。

  • 被重写的方法不能是 final 或 static 方法:

final 方法不能被重写,而 static 方法与类关联而非实例关联,因此也不适用于重写​​​​​​​

重写的示例

下面是一个简单的Java示例,展示了如何重写父类的方法:

class Animal {  
    public void makeSound() {  
        System.out.println("Some generic animal sound");  
    }  
}  
  
class Dog extends Animal {  
    @Override // 注解表明此方法是重写父类方法  
    public void makeSound() {  
        System.out.println("Bark");  
    }  
}  
  
public class MethodOverridingExample {  
    public static void main(String[] args) {  
        Animal animal = new Dog(); // Animal类型的引用指向Dog类型的对象  
        animal.makeSound(); // 输出"Bark",因为Dog类重写了makeSound方法  
    }  
}

在这个例子中,Dog 类继承了 Animal 类,并重写了 makeSound 方法。当我们通过 Animal 类型的引用调用 makeSound 方法时,实际上调用的是 Dog 类中重写后的 makeSound 方法,输出“Bark”。


重载与重写的区别

  • 重写发生在父类和子类之间,子类提供与父类相同方法签名的新实现。
  • 重载发生在同一个类中,允许多个方法拥有相同的名字,但参数列表不同(参数数量、类型或顺序不同)。

动态绑定

在Java中,动态绑定(Dynamic Binding)是一个核心概念,它允许在运行时根据对象的实际类型来确定调用哪个方法。这种机制是实现多态性的关键,使得程序能够在运行时灵活地处理不同类型的对象。

定义

动态绑定是指在程序运行过程中,根据具体的实例对象来确定调用哪个方法的过程。它不同于静态绑定(前期绑定),后者在编译时就已经确定了方法的调用关系。

多态性的实现

  • 动态绑定是实现多态性的重要因素。多态性允许我们使用父类类型的引用来引用子类的对象,并在运行时确定实际调用的方法。这种机制增加了程序的灵活性和可扩展性。
  • 例如,假设有一个父类 Animal 和一个子类 Dog ,Dog 类重写了 Animal 类的 makeSound() 方法。当我们创建一个 Dog 对象并将其赋值给一个 Animal 类型的引用时,通过该引用调用 makeSound() 方法,会动态地绑定到 Dog 类的实现上。

与静态绑定的区别

  • 静态绑定(也称为前期绑定或编译时绑定)是在编译时就已经确定了方法的调用关系。它通常用于调用静态方法、私有方法、构造方法以及使用 final 修饰的方法等。
  • 动态绑定则是在运行时根据对象的实际类型来确定方法的调用关系。它主要用于实现多态性,使得程序能够更加灵活和可扩展。

示例

class Animal {  
    void makeSound() {  
        System.out.println("Animal sound");  
    }  
}  
  
class Dog extends Animal {  
    @Override  
    void makeSound() {  
        System.out.println("Bark");  
    }  
}  
  
public class DynamicBindingExample {  
    public static void main(String[] args) {  
        Animal animal = new Dog(); // 向上转型  
        animal.makeSound(); // 动态绑定到Dog类的makeSound()方法上  
    }  
}

在上述示例中,当我们通过父类类型的引用 animal 调用 makeSound() 方法时,会动态地绑定到 Dog 类的实现上,输出“Bark”。这就是动态绑定的一个典型应用示例。

注意事项

  • 动态绑定只适用于实例方法,不适用于静态方法、私有方法和构造方法。这是因为这些方法在编译时就已经确定了调用关系,无法进行动态绑定。
  • 使用 final 修饰的方法也无法进行动态绑定,因为它们不能被重写。

多态

在Java编程语言中,多态性是面向对象编程的三大特性之一,它允许一个接口(或基类引用)被多种数据类型所实现,并根据实际的类型执行对应的方法。以下是关于Java中多态的详细介绍:

定义

多态(Polymorphism)是指允许一个接口(或父类引用)引用多种实际类型,并且可以根据实际的类型来执行对应的方法。简言之,就是同一个方法调用可以有不同的实现方式。

实现方式

Java中多态的实现主要依赖于继承和方法重写。

  • 继承:子类可以继承父类的方法定义和属性,从而具备相同的方法签名。
  • 方法重写(覆盖):子类可以对继承自父类的方法进行重写,即在子类中重新定义与父类相同签名的方法。

实现原理

多态的实现原理主要基于动态绑定(Dynamic Binding),也称为后期绑定。在运行时,Java虚拟机会根据对象的实际类型来确定调用哪个重写后的方法。这种机制使得相同的消息(即方法调用)可以根据不同的对象而具有不同的行为。

应用场景

多态在Java编程中有广泛的应用,以下是几个常见的应用场景:

  • 接口和抽象类的使用:通过定义接口或抽象类,并在父类中声明一组方法,具体实现留给子类。这样,不同的子类可以实现各自独特的行为。
  • 方法重写和回调机制:在父类中定义一个回调方法,子类重写该方法,并由父类对象调用。这样,根据不同的子类实现,可以执行相应的逻辑。

示例

假设有一个 Animal 类和两个子类 Dog 和 Cat,每个类都有一个 makeSound 方法。通过多态,我们可以使用一个 Animal 类型的引用来引用 Dog 或 Cat 对象,并调用它们的 makeSound 方法。在运行时,Java虚拟机会根据对象的实际类型(Dog 或 Cat)来确定调用哪个实现。

Animal animal1 = new Dog();  
Animal animal2 = new Cat();  
  
animal1.makeSound(); // 输出 "Woof!"  
animal2.makeSound(); // 输出 "Meow!"

意义

多态性提高了代码的灵活性和可扩展性。通过多态,我们可以编写更加通用的代码,而无需关心具体的实现细节。这使得代码更加易于维护和扩展。

注意事项

  • 多态只适用于实例方法,不适用于静态方法。因为静态方法与类关联,而不是与实例关联。
  • 多态的实现需要满足两个条件:一是方法必须在子类中被重写;二是必须通过父类引用

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

STM32 | STC-USB驱动安装Windows 10(64 位)

Windows 10(64 位)安装方法 由于 Windows10 64 位操作系统在默认状态下,对于没有数字签名的驱动程序是不能安装成功的。所以在安装 STC-USB 驱动前,需要按照如下步骤,暂时跳过数字签名,即可顺利安装成功。…

回归预测 | Matlab实现GA-LSSVM遗传算法优化最小二乘支持向量机多输入单输出回归预测

回归预测 | Matlab实现GA-LSSVM遗传算法优化最小二乘支持向量机多输入单输出回归预测 目录 回归预测 | Matlab实现GA-LSSVM遗传算法优化最小二乘支持向量机多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 Matlab实现GA-LSSVM遗传算法优化最小…

纯CSS实现步骤条

纯CSS实现纵向Steps步骤条效果 效果图 实现思路 步骤条是一种用于引导用户按照特定流程完成任务的导航条,在各种分步表单交互场景中广泛应用。步骤条通常由编号、名称和引导线三个基本要素组成。本文中要实现的是一个简单的步骤条,包含上述三个基本要素…

Python爬虫实战:爬取【某旅游交通出行类网站中国内热门景点】的评论数据,使用Re、BeautifulSoup与Xpath三种方式解析数据,代码完整

一、分析爬取网页: 1、网址 https://travel.qunar.com/2、 打开网站,找到要爬取的网页 https://travel.qunar.com/p-cs299979-chongqing进来之后,找到评论界面,如下所示:在这里我选择驴友点评数据爬取点击【驴友点评…

天下大爱唯母爱

岁月轮转,人生寻常,又逢一年母亲节。作为子女,这是所有人都参与节日,也是每一位母亲在繁忙日常中,一个短暂的休息,停下手中的忙碌,听孩子的一声祝福:妈妈辛苦了,母亲节快…

树莓派4B-搭建一个本地车牌识别服务器

实现目标: 一、设备自启后能够获得服务的ip与端口号,用于计算机连接设备; 二、计算机可以通过服务ip与端口访问设备服务; 三、上传需要处理的数据,返回结果反馈给用户; 四、上传到服务器的数据不会导致设备…

车载测试系列:CAPL脚本语法

HFP测试内容与测试方法 2.3 接听来电:测试手机来电时,能否从车载蓝牙设备和手机侧正常接听】拒接、通话是否正常。 1、预置条件:待测手机与车载车载设备处于连接状态 2、测试步骤: 1)用辅助测试机拨打待测手机&…

本地电脑hosts强制解析指定IP的方法

网站接入CDN后,很多时候需要本地强制解析回源查看状态,比如查看是不是源服务器故障,网站修改是否正确,网站更新是否及时,故障查看是CDN问题还是源服务器问题,都需要hosts回源。 今天云加速教大家如何本地电…

AI工具摸索-关于写作(1)

虽然人工智能工具非常多,但是如果想要成为生产力,能达标的工具仍然非常少,除了最常用的chatgpt,其他的工具真的能达标吗,这篇文章主要就是对比市面上的一些工具, 但我这个人非常执拗,我认为作为生产力工具的功能必然是可以真正帮助我们的,而不是说作为一个写作工具结…

docker部署springboot+Vue项目

项目介绍:后台springboot项目,该项目环境mysql、redis 。前台Vue:使用nginx反向代理 方法一:docker run 手动逐个启动容器 1.docker配置nginx代理 将vue项目打包上传到服务器上。创建文件夹存储数据卷,html存放打包…

【Dash】开始学习dash

安装Dash 网上很多安装dash的教程,不再赘述 开始Dash 一个dash页面的基本写法 # dash 的基本写法 import dash from dash import html,dcc,callback,Input,Output# 创建一个 dash 应用 app dash.Dash()# 定义布局,定义一个输入框和一个输出框 app.l…

NIOS II实现LED流水灯以及串口输出(DE2-115开发板)

NIOS II实现LED流水灯以及串口输出(DE2-115开发板) 前言什么是Qsys?什么是NIOSII?注意事项1、管脚配置2、配置NIOSII时的连接3、注意中断配置好后是这样的4、注意名称的配置5、设置双功能引脚 NIOS II的报错代码以及效果演示流水灯输出到电脑串口助手 …

【020】基于JavaWeb实现的批报管理系统

项目介绍 基于jspservlet实现的批报管理系统采用B/S架构,该项目设计了一个角色管理员,管理员实现了我的案件、查询统计、项目维护等三大功能模块 技术栈 开发工具:Idea2020.3 运行环境:jdk1.8tomcat9.0mysql5.7 服务端技术:j…

【机器学习数据可视化-04】Pyecharts数据可视化宝典

一、引言 在大数据和信息爆炸的时代,数据可视化成为了信息传递和展示的关键手段。通过直观的图表和图形,我们能够更好地理解数据,挖掘其背后的信息。Pyecharts,作为一款基于Python的数据可视化库,凭借其丰富的图表类型…

获取Linux上的Redis的用户名、密码、端口、host等信息

目录 进入redis-cli的目录 启动./redis-cli服务 查询密码 查询用户名 查询端口 查询host 参考文章:解决redis-cli连接时出现Could not connect to Redis at 127.0.0.1:6379: Connection refused-阿里云开发者社区 (aliyun.com) linux查看redis用户和密码_mo…

Java构造方法详解

在Java方法内部定义一个局部变量时,必须要初始化,否则就会编译失败,如下: 要让上述代码通过编译,只需在使用a之前给a赋一个初始值即可 如果是对象:下面用一个日期类演示 我们没有给年月日赋值,…

纯血鸿蒙APP实战开发——首页下拉进入二楼效果案例

介绍 本示例主要介绍了利用position和onTouch来实现首页下拉进入二楼、二楼上划进入首页的效果场景,利用translate和opacity实现动效的移动和缩放,并将界面沉浸式(全屏)显示。 效果图预览 使用说明 向下滑动首页页面超过触发距…

实验室纳新宣讲会(java后端)

前言 2024-5-12 22:00:39 这是陈旧已久的草稿 2021-09-16 15:41:38 发布一下 当时我进入实验室,也是大二了,实验室纳新需要宣讲, 但是当时有疫情,又没宣讲成。 实验室纳新宣讲会(java后端) 首先&#x…

【计算机网络】物理层 通信基础、奈氏准则、香农公式 习题2

下列说法中正确的是( )。 A. 信道与通信电路类似,一条可通信的电路往往包含一个信道 B.调制是指把模拟数据转换为数字信号的过程 C. 信息传输速率是指通信信道上每秒传输的码元数 D.在数值上,波特率等于比特率与每符号所含的比特数的比值 信息传输速率&a…

【进程通信】了解信号以及信号的产生

文章目录 0.前言1.信号的基本概念1.1中断1.1.1 软中断1.1.2硬中断 1.2异步1.2.1异步和同步的比较 2.信号的主要用途3.信号的特点4.查看信号4.1Core和Term的区别4.2生成Core文件 5.初识捕捉信号5.1signal函数 6.产生信号的方式6.1.通过终端按键产生信号6.2.调用系统函数向进程发…