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

news2024/11/24 7:04:42

目录

一个生动形象的例子

场景设定

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!"

意义

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

注意事项

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

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

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

相关文章

【必看】Spring系列面试题

Spring Core Container, AOP, Data Access, Web... 基础 1. 简单介绍Spring 一款开源的轻量级 Java 开发框架,旨在提高开发人员的开发效率以及系统的可维护性。Spring 支持 IoC(Inversion of Control:控制反转) 和 AOP(Aspect-Oriented Pro…

【JVM类加载机制】深度剖析JVM类加载机制

深度剖析JVM类加载机制 前言类加载运行全过程loadClass的类加载过程 类加载器和双亲委派机制类加载器的类型类加载器的初始化过程双亲委派机制为什么要设置双亲委派机制?全盘负责委托机制自定义类加载器实例打破双亲委派机制Tomcat打破双亲委派机制Tomcat自定义加载…

[华为OD]BFS C卷 200 智能驾驶

题目: 有一辆汽车需要从m*n的地图的左上角(起点)开往地图的右下角(终点),去往每一个地区都需 要消耗一定的油量,加油站可进行加油 请你计算汽车确保从起点到达终点时所需的最少初始油量说明: (1)智能汽车可以上下左右四个方向…

Python中的`__init__.py`文件:它的作用和重要性

引言 在Python的世界里,__init__.py文件是一个特殊的存在。对于初学者来说,它可能看起来有些神秘,但对于理解Python的包和模块系统来说,它起着至关重要的作用。本文将详细解释__init__.py文件的功能、它在Python项目中的作用&…

Threejs实现PMD模型眨眼说话等功能

上个章节通过加载PMD模型和VMD的动作播放MMD的动画,这节通过js控制让模型实现眨眼,说话。我们还是拿上个模型来操作,首先是创建好Threejs的场景,包括灯光,相机,渲染器等。 initScene(){this.scene new THR…

【Linux】Centos7安装部署unimrcp,搭建MRCP服务器

yum install libtool yum install libtool-ltdl-devel yum install libsofia-sip-ua find / -name libsofia-sip-ua.so.0 2>/dev/null # 设置环境变量:如果库文件存在但不在默认搜索路径中,你可以通过设置 LD_LIBRARY_PATH 环境变量来告诉系统在哪…

语音转文字服务的调用接口

语音转文字(Speech-to-Text,STT)技术允许将口语化的语音转换成书面文字。以下是一些提供语音转文字服务的调用接口及其特点。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合作。 1.讯飞开放平台语音转写…

[图解]实现领域驱动设计译文暴露的问题03

0 00:00:02,960 --> 00:00:04,940 前面我们讲了 1 00:00:05,260 --> 00:00:06,810 第①句话的 2 00:00:07,090 --> 00:00:09,750 第(1)个问题和第(2)个问题 3 00:00:13,920 --> 00:00:16,930 共享父类的对象&#…

【软件安装】vmware虚拟机安装完整教程(15.5版本)

安装包-百度网盘: 链接:https://pan.baidu.com/s/1zwYeRVdp1TM75JIctkWqVA?pwd6666 提取码:6666 1、去BIOS里修改设置开启虚拟化设备支持(这一步必须要进行) 网址:https://jingyan.baidu.com/article…

抖音小店怎么运营才能出单呢?就这一个步骤做好,爆单不是梦!

哈喽~我是电商月月 新手做抖音小店绝对会有这两个问题:怎么运营?不出单怎么办?被这两个问题困扰着的商家,别着急! 看完我这一篇分享,你就知道自己的问题所在了! 抖音小店的运营中&#xff0c…

1070: 邻接矩阵存储简单路径

解法&#xff1a; #include<iostream> #include<vector> using namespace std; int arr[100][100]; int n; int sta, des; vector<int> path; vector<vector<int>> res; void dfs(vector<int> &a,int i) {a[i] 1;path.push_back(i);…

ICode国际青少年编程竞赛- Python-2级训练场-列表遍历

ICode国际青少年编程竞赛- Python-2级训练场-列表遍历 1、 for i in range(3):Flyer[i].step(2) Dev.step(6)2、 for i in range(7):Flyer[i].step() Dev.step(Item.x - Dev.x)3、 for i in range(3):Flyer[i].step(1) Dev.step(4) Dev.turnLeft() Dev.step(2) Dev.turnL…

宝塔环境安装+安装软件教程

游戏&#xff0c;大型网站程序等都安装在服务器上&#xff0c;服务器用的是Linux系统&#xff0c;进行服务器维护需要记住很多linux的命令&#xff0c;这就很麻烦。 宝塔的好处&#xff0c;就是通过一个交互界面就能完成服务器的维护工作&#xff0c;比如更新系统&#xff0c;添…

24.5.12(23广东,19陕西)(字典树)

星期一&#xff1a; dp题单 区间dp第三题 二叉搜索树 cf传送门 思路&#xff1a;dp【i】【j】【0/1】表示区间 i到 j&#xff0c;以 i / j为根节点能否形成一棵二叉搜索树 因为题目要求组成二叉搜索树&#xff0c;若 i 到 j 的节点为一颗完整的子…

信创应用软件之国产邮箱

信创应用软件之国产邮箱 文章目录 信创应用软件之国产邮箱采用信创邮箱的必要性信创邮箱采购需求国产邮箱业务形态国产邮箱代表性品牌CoremailRichmail安宁eyouUMail拓波 邮件安全的发展阶段 采用信创邮箱的必要性 邮箱是天然的数据存储空间&#xff0c;党政和央国企客户在使用…

每日OJ题_贪心算法四⑦_力扣1054. 距离相等的条形码

目录 力扣1054. 距离相等的条形码 解析代码 力扣1054. 距离相等的条形码 1054. 距离相等的条形码 难度 中等 在一个仓库里&#xff0c;有一排条形码&#xff0c;其中第 i 个条形码为 barcodes[i]。 请你重新排列这些条形码&#xff0c;使其中任意两个相邻的条形码不能相等…

十六、Redis和数据库双写一致性问题

众所周知&#xff0c;Redis一般被用来做为数据的缓存中间件&#xff0c;提升系统读数据的能力。但是被缓存的数据并不是一成不变的。如果是永远不会变的&#xff0c;那不会存在双写一致性问题(只需构建一次缓存即可)。但是大部分情况下&#xff0c;或多或少都会涉及到缓存数据的…

发布一下之前的草稿和仅我可见【个人】

发布一下之前的草稿和仅我可见【个人】 前言版权推荐发布一下之前的草稿和仅我可见【个人】java面试面试真题笔试真题 最后 前言 2024-5-13 12:26:55 发布一下之前的草稿和仅我可见 这些一般多事和面试相关的内容 以下内容源自《【创作模板】》 仅供学习交流使用 版权 禁止…

禅道远程安装配置(cpolar)

1. 禅道安装 2. cpolar下载安装 Cpolar的下载可以直接登录cpolar官网&#xff08;www.cpolar.com&#xff09;&#xff0c;下载对应版本即可 download下载 - cpolar 极点云官网 2.1 cpolar官网注册账号 2.2 macOS可以通过brew安装 Cpolar快速入门教程&#xff1a;macOS系列…

16-LINUX--线程安全

一。线程安全 线程安全即就是在多线程运行的时候&#xff0c;不论线程的调度顺序怎样&#xff0c;最终的结果都是 一样的、正确的。那么就说这些线程是安全的。 要保证线程安全需要做到&#xff1a; 1&#xff09; 对线程同步&#xff0c;保证同一时刻只有一个线程访问临界资…