Java——多态

1.多态简介

        多态,字面意思来看就是多种形态,即当去执行某个行为,会因为对象的不同而产生不同的效果。在java语言当中就是根据对象的性质不同,对同一个方法进行调用时,得到了不同的执行结果。

        在理解多态中必须时刻牢记三个条件:

(1)存在继承关系,并且发生向上转型。

(2)子类对父类的方法进行重写。

(3)通过父类对象的引用去调用这个重写的方法。

        在满足了如上三个条件后,就会发生动态绑定,而动态绑定则是多态的基础。

         接下来,我们将会对刚才涉及到的概念进行一一解释。

2.向上转型和向下转型

        我们知道,在继承关系中存在父类和子类,父类对象和子类对象之间可以存在类型转换。当我们将子类对象赋值给父类对象,这就构成了向上转型;当我们将父类对象赋值给子类对象,这就构成了向下转型。

        需要指出的是,当对象进行向上转型后,就不可以再调用子类特有的方法了。如果想要调用子类方法,那么就需要进行向下转型还原为子类对象。

2.1 向上转型

        向上转型:将子类对象赋值给父类对象

        向上转型常见发生情况:

直接赋值

class Base{}class Derived extends Base{}public class Test {public static void main(String[] args) {Base b1 = new Derived();    //直接赋值}
}

作为方法的参数,将子类对象实参传给父类对象形参

class Base{}class Derived extends Base{}public class Test {public static void func(Base b){}public static void main(String[] args) {Derived d = new Derived();func(d);    //传参}
}

作为返回值,将子类对象以父类对象的形式返回

class Base{}class Derived extends Base{}public class Test {public static Base func(){Derived d = new Derived();return d;}public static void main(String[] args) {func(); //返回值}
}

2.2 向下转型

        向下转型:将父类对象赋值给子类对象

        向下转型具体来说就是将一个子类对象向上转型后的父类对象还原为其原来的子类对象。由于向下转型存在着安全性问题,所以向下转型的时候需要强制类型转换。

class Base{}class Derived extends Base{}public class Test {public static void main(String[] args) {Derived d = (Derived) new Base();}
}

        不完全主要是因为父类可以被很多类继承,所以父类拥有众多子类,无法肯定将要向下转型的对象是不是就是指定的子类,所以存在安全性问题。这时候就需要使用instanceof关键字对对象进行检查,如果是指定子类向上转型的对象,则表达式为真。

class Base{}
class Derived1 extends Base{public void func(){System.out.println("Derived1");}
}
class Derived2 extends Base{public void func(){System.out.println("Derived2");}
}
public class Test {public static void main(String[] args) {Base b1 = new Derived1();if(b1 instanceof Derived2){Derived2 d = (Derived2)b1;d.func();}if(b1 instanceof Derived1){Derived1 d = (Derived1)b1;d.func();}}
}

Derived1

3. 重写

3.1 重写的实现

        重写就是子类对父类的方法进行重新编写,所以要求重写的方法除了方法体以外,函数名、返回值、参数等都不可以改变。

class Base{public void func(){System.out.println("Base::func()");}
}class Derived extends Base{@Overridepublic void func(){System.out.println("Derived::func()");}
}

        在实现重写的过程中存在如下需要注意的关键点:

①重写是父类和子类方法之间的关系,所以重写必然依附于继承关系

②子类中重写的方法和父类的方法相比,返回值、方法名、参数列表必须完全一致

③被重写的方法的访问修饰限定符,子类必须大于等于父类的

private修饰的方法不可以重写,因为在子类中都无法访问到这个方法。

static修饰的方法不可以重写

final修饰的方法不可以重写,这也正是final修饰方法的作用。

构造方法不可以被重写

⑧代码中存在一行:@Override 。这是一个注解,他是用于提示我们也是在告诉编译器接下来写的方法是一个重写方法,所以编译器就会进行检查,当发现不是重写方法的时候就会报错。

3.2 重写的使用

        那么重写有什么作用呢?我们可以通过代码进行测试:

class Base{public void func(){System.out.println("Base::func()");}
}class Derived extends Base{public void func(){System.out.println("Derived::func()");}
}public class Test {public static void main(String[] args) {Base b = new Derived();b.func();}
}

Derived::func()

        可以发现当我们使用向上转型后的对象调用重写方法的时候,对象调用了子类的方法。这个向上转型对象调用子类重写方法的过程,由于在编译时不确定方法的行为,所以需要等到程序运行时才能确定,因此称为动态绑定。同样的,一般的函数(包括函数重载),都是可以在编译时根据所传递的信息(如函数名、参数)等,就可以确定所调用的方法,因而称谓静态绑定。

        在有了如上基础后,我们就可以再来理解一下之前的toString。首先需要明确的一点,所有类的父类都默认是Object(一个java中提供的类),而Object中有toString方法。当我们的类(子类)不实现toString的时候,就会默认调用父类的toString方法;当我们自己写了toString方法后就构成了重写,所以这个时候再调用toString,根据继承关系子类优先原则,就会先调用子类的方法。所以会发现,toString方法的访问限定符只可以是public,这就是重写在发挥作用。

4.总结

        在父类的构造方法中是可以调用子类的重写方法的,但是由于子类初始化在父类之后,所以会产生问题,不建议这样使用。

        通过以上的介绍,可以为多态下一个定义了,多态就是对不同对象尽管看似调用了同一种方法,但是由于对象是向上转型的,方法是存在重写的,所以相当于父类对象调用了不同的子类的重写的方法,因此形成了多态。

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

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

相关文章

文件夹变白色文件,数据恢复全攻略助你轻松找回!

在日常的电脑使用中,你是否曾遇到过文件夹突然变成了白色文件的情况?这种看似无害的变化,实则可能隐藏着数据丢失的风险。当你发现原本正常的文件夹图标变成了无关联程序的白板图标,且无法正常打开时,内心无疑是焦虑不…

车载诊断系统应用方案选型,ESP8266方案让成本降低了35%,销售数据提升47%

车载诊断系统简称OBD,这个系统随时监控发动机的运行状况和尾气后处理系统的工作状态,一旦发现有可能引起排放超标的情况,会马上发出警示。当系统出现故障时,故障灯(MIL)或检查发动机(Check Engine)警告灯亮,同时OBD系统…

Java调用cmd

Java调用cmd并执行命令 在Java中调用命令提示符(cmd)并执行命令,可以通过使用Runtime类或ProcessBuilder类来实现 代码示例 /*** 在指定目录下执行命令。** param command 要执行的命令* param path 命令执行的路径* return 如果命令成功执…

【JavaWeb】Day50.Mybatis的XML配置文件

XML配置文件规范 使用Mybatis的注解方式,主要是来完成一些简单的增删改查功能。如果需要实现复杂的SQL功能,建议使用XML来配置映射语句,也就是将SQL语句写在XML配置文件中。 在Mybatis中使用XML映射文件方式开发,需要符合一定的规…

C语言之文件操作【万字详解】

目录 一.什么是文件? 二.为什么要使用文件? 三.文件的分类 3.1.程序文件 3.2.数据文件 四.二进制文件和文本文件 五.文件的打开和关闭 (重点) 5.1流和标准流 5.1.1何为流? 5.1.2.标准流 5.2文件指针 5.3文件的打开和关…

【1425】java 外籍人员管理系统Myeclipse开发mysql数据库web结构jsp编程servlet计算机网页项目

一、源码特点 java 外籍人员管理系统是一套完善的java web信息管理系统 采用serlvetdaobean,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式 开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff…

机器学习波士顿房价

流程 数据获取导入需要的包引入文件,查看内容划分训练集和测试集调用模型查看准确率 数据获取 链接:https://pan.baidu.com/s/1deECYRPQFx8h28BvoZcbWw?pwdft5a 提取码:ft5a --来自百度网盘超级会员V1的分享导入需要的包 import pandas as pd imp…

回归预测 | Matlab实现SA-BP模拟退火算法优化BP神经网络多变量回归预测

回归预测 | Matlab实现SA-BP模拟退火算法优化BP神经网络多变量回归预测 目录 回归预测 | Matlab实现SA-BP模拟退火算法优化BP神经网络多变量回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab实现SA-BP模拟退火算法优化BP神经网络多变量回归预测&#xff0…

Vue3+Spring Boot3实现跨域通信解决办法

Vue3Spring Boot3实现跨域通信解决办法 1 跨域是什么?2 何为同源呢?3 解决办法3.1 全局配置3.1.1 实现CorsFilter过滤器3.1.2 实现SpringMVC配置类3.1.3 创建CorsFilterFactory工厂类返回CorsFilter对象 3.2 局部跨域3.2.1 注解配置3.2.2 手动设置响应头(局部跨域)…

几款AI语音克隆使用分享(未完成)

近期在看AI语音克隆,发现很多的语音克隆对于原始的音频或者朗读者要求过高,不知各位懂的有没有能给推荐个靠谱的。 1、剪映 语音克隆,2个字1积分,600积分6元。贵,多充并没有优惠。 声音相似度高,但是&#…

springboot+vue社区报修便民维修网站设计与实现

便民维修网站,主要的模块包括管理员;首页、个人中心、管理员管理、用户管理、维修人员管理、在线报修管理、联系客服管理、公司回访管理、基础数据管理、论坛管理、公告管理、轮播图信息,维修人员;首页、个人中心、维修人员评价管…

科研基础与工具(论文搜索)

免责申明: 本文内容只是学习笔记,不代表个人观点,希望各位看官自行甄别 参考文献 科研基础与工具(YouTube) 搜索论文 Google Scholar 谷歌学术 涵盖面太全了,都收录,就会有很多低质量的论文…

基于SpringBoot民宿入住管理系统

目录 项目介绍 图片展示 运行环境 获取方式 项目介绍 权限划分:用户和管理员 用户: 具有登录、注册、退出登录的功能 首页:可以查看民宿房间总数,保洁人数,当前入住人数,合计总入住人数,以…

【架构】Elasticsearch+Logstash+Kibana架构

目录 什么是ELK ELK架构的应用场景 什么是ELK ELK是由Elasticsearch、Logstash和Kibana三个开源项目组成的技术栈,广泛用于搜索、日志管理和日志分析。这三个组件协同工作,提供了一个强大的方法来收集、存储、搜索和可视化日志数据和其他时间序列数据…

Android Jetpack学习系列——Room

关于Room: Room是Android Jetpack组件之一,旨在为Android应用程序提供一种简单、强大且易于使用的本地数据库访问解决方案。 关键特性: 1.基于SQLite封装:Room是基于SQLite数据库引擎构建的,提供了面向对象的API来与…

代码随想录算法训练营第五十二天|leetcode第84题

一、leetcode第84题 本题要求柱状图中能勾勒出的最大矩形面积,使用单调栈,要求出单调栈栈顶元素左右比其小的第一个元素,因此使用递减栈,在遇到比栈顶元素小的元素时以栈顶元素为基准计算最大矩形面积。为了避免单调递减无法计算…

2-搭建开发环境

1.2 搭建开发环境 这次课我们来搭建开发环境,在搭建环境之前,我想先强调几点: 作为一个开发者,你应该养成一个好的习惯,你安装的所有的开发工具,都应该把它放到英文的,并且没有空格的路径之下…

stm32开发之threadx+modulex+filex+shell组件(实现命令行动态加载程序)

前言 前几篇博客基本上已经将filex、levelx、threadx、modulex、shell 组件大概都记录了一遍.本篇博客做个综合实际案例记录. 实现效果 代码程序 Modulex组件 源文件 /** Copyright (c) 2024-2024,shchl** SPDX-License-Identifier: Apache-2.0** Change Logs:…

基于Python的招聘岗位数据分析系统的设计与实现

基于Python的招聘岗位数据分析系统的设计与实现 Design and Implementation of a Job Recruitment Data Analysis System based on Python 完整下载链接:基于Python的招聘岗位数据分析系统的设计与实现 文章目录 基于Python的招聘岗位数据分析系统的设计与实现摘要第一章 绪论…

2024年学浪的缓存怎么导出来

在自我成长的道路上,越来越多的朋友选择通过精选课程来提升自己。然而,面对那些服务期限有限的课程,怎样才能把握住知识的光芒,让它照亮未来的每一个角落?本文就教大家如何利用工具下载学浪app平台的课程 工具我已经打…