面向对象的特征之三:多态性

news2024/12/22 23:47:43

文章目录

  • 一、理解多态性
  • 二、什么是多态性
  • 三、多态性的使用——虚拟方法调用
  • 四、多态性使用前提
  • 五、适用范围
  • 六、虚拟方法调用详细介绍
    • 多态性是编译期的还是运行期的?
      • 举例
  • 每日一考
  • 七、instanceof关键字的使用
    • 引入:关于多态性的讨论
    • 向下转型:instanceof
  • 练习1
  • 练习2

一、理解多态性

多态性:可以理解为一个事物的多种形态

二、什么是多态性

对象的多态性:父类的引用指向子类的对象(子类的对象赋给父类的引用)

//假设父类是Person,子类是Man和Woman,对象的多态性体现为:
Person p1=new Man();
Person p2=new Woman();

三、多态性的使用——虚拟方法调用

多态性的使用:当调用子父类同名同参数的方法时,实际执行的是子类重写父类的方法。
有了对象的多态性后,在编译期,我们只能调用父类中声明的方法。但在运行期,我们实际执行的是子类重写父类的方法。
总结:编译看左边,执行看右边。

四、多态性使用前提

①有类的继承关系
②一般会有重写(不然不用多态性,因为子类和父类中的方法一样,没有意义)

五、适用范围

多态性只适用于方法,不适用于属性
也就是说,如果子类和父类中有同名的属性,之后有了多态性,在调用这个属性时,最终调用的是父类中的属性。(属性的编译和运行都看左边)即看Person,不是Man

Person p=new Man();

六、虚拟方法调用详细介绍

子类中定义了与父类同名同参数的方法,在多态的情况下,将此时父类的方法称为虚拟方法(因为子类一般会重写父类的方法,所以父类的方法只是书面上存在,即虚拟存在,最终调用的其实是子类重写后的方法)。父类根据赋给它的不同子类对象,动态调用子类的方法,这样的方法调用在编译期是无法确定的。

多态性是编译期的还是运行期的?

运行期的

举例

import java.util.Random;

//面试题:多态是编译时行为还是运行时行为?
//证明如下:
class Animal  {
 
	protected void eat() {
		System.out.println("animal eat food");
	}
}

class Cat  extends Animal  {
 
	protected void eat() {
		System.out.println("cat eat fish");
	}
}

class Dog  extends Animal  {
 
	public void eat() {
		System.out.println("Dog eat bone");

	}

}

class Sheep  extends Animal  {
 

	public void eat() {
		System.out.println("Sheep eat grass");

	}

 
}

public class InterviewTest {

	public static Animal  getInstance(int key) {
		switch (key) {
		case 0:
			return new Cat ();
		case 1:
			return new Dog ();
		default:
			return new Sheep ();
		}

	}

	public static void main(String[] args) {
		int key = new Random().nextInt(3);

		System.out.println(key);

		Animal  animal = getInstance(key);
		
		animal.eat();//这个方法的调用取决于创建的对象是什么类的,不能一下看出来,所以不是编译期的
		 
	}

}

每日一考

在这里插入图片描述
答案
在这里插入图片描述
在这里插入图片描述
私有的属性提供的get、set方法,子类中可以通过调用这两个方法对private属性进行调用。private方法可以通过父类中的权限较大的方法调用,然后子类调用这个权限较大的方法。
在这里插入图片描述
在这里插入图片描述

七、instanceof关键字的使用

引入:关于多态性的讨论

Person p2=new Man();//Person是父类,Man是子类
p2.earnMoney();//如果earnMoney是子类Man特有的方法,这里会出错
p2.isSmoking=true;//如果isSmoking是子类Man特有的属性,这里会出错

【原因】不能调用子类所特有的属性和方法,因为对象p2是Person型的。

有了对象的多态性后,内存中实际上加载的子类对象中特有的属性和方法,但由于变量声明为父类型,导致编译时只能调用父类中声明的属性和方法。

那如何调用子类中特有的属性和方法?
向下转型:使用强制类型转换符。

Man m1=(Man)p2;
m2.earnMoney();//不会出错
m2.isSmoking=true;//不会出错

【注意】但是,强转时可能出现ClassCastException的异常,所以引入关键字instanceof

向下转型:instanceof

为了避免在向下转型过程中出现ClassCastException的异常,我们在向下转型之前先进性instanceof的判断。一旦返回true,就进行向下转型;返回false,不进行。

if (p2 instanceof Woman){
	Woman w1=(Woman)p2;
	w1.shopping();
}
if (p2 instanceof Man){
	Man m2=(Man)p2;
	w2.earnMoney();
}

如果B是A的父类,a instanceof A返回true,则a instanceof B也返回true。反之不一定。
但是由于在前面有Person p2=new Man(); 也就是new的就是Man的对象,那在instanceof判断时一定是true。

练习1

声明的子、父类:
在这里插入图片描述
问题(输出的值):
在这里插入图片描述

答案:
1、20(此时还不涉及多态性,因为创建的是sub对象且赋给的也是sub类型变量,属性就是sub的,如果sub和base中定义的属性不同名,输出的是sub.base的属性名,那么this会先在sub定义的属性中找,没有;然后在去父类定义的属性找,输出的是父类的属性值)
2、20()
3、true,因为==对于引用数据类型来讲,比较的是两个引用数据类型的地址值是否相同
4、10,涉及到多态性,编译看左边
5、20,涉及到多态性,编译看左边,运行看右边
【提示】在真正编译时,子、父类中不要出现同名的属性,容易混

练习2

1、问题:输出的结果?
在这里插入图片描述
2、
在这里插入图片描述

已有的类型定义:
在这里插入图片描述
答案:
1、sub_1,因为sub1中的int[] arr和base1中的int…arr是一样的,所以sub1和base1中的方法构成了重写。多态性赋给的父类变量是base1类型,所以调用的是base1中的方法add,而sub1中能与base1中的方法add构成重写的只有int[] arr,而不是int b,int c,所以不会调用sub1中的第二个方法。
2、sub_2,强制向下转型后,是调用sub1中的方法,而sub1中能和add(1,2,3)严丝合缝的是add(int a,int b,int c)这个方法

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

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

相关文章

Linux-7 文本编辑vi/vim

Linux-7 文本编辑vi/vim vim介绍 什么是vim? vi和vim是Linux下的一个文本编辑工具。(可以李姐为Windows的记事本或word文档) 为什么要使用vim? 因为Linux系统一切皆为文件,而我们工作最多的就是修改某个服务的配置&a…

网络安全——投票系统缺陷(靶场实战)

我们需要利用漏洞来把投票信息刷到第一位 我们可以利用 HTTP_X_FORWARDED_FOR 来进行获取伪造 我们再次进行投票的时候,我们抓取数据包的格式 我们采用上述方法进行伪造 增加变量,我们采用多IP攻击 选中247点击send to Intruder 选中247和1点击 add&…

基于Xlinx的时序分析与约束(8)----关于时序路径、时钟悲观度和建立时间/保持时间的一些问题

写在前面 最近研究vivado里的时序分析路径时,发现了3个很有意思的问题。经过一番查找资料后,总算把问题搞明白了,在这里分享给大家。 1、为什么同一条时序路径在报表里的值不一样? 在如下文件建立的工程中: module te…

Window10下配置Maxim SDK

参考网址: 微信(中文):【嵌入式AI开发&Maxim篇一】美信Maxim78000Evaluation Kit AI部署流程初探 GitHub:MaximAI_Documentation/MAX78000_Feather at master MaximIntegratedAI/MaximAI_Documentation 下载地址…

【回答问题】ChatGPT上线了!如何安装python-ipopt?python-ipopt有哪些用法?

如何安装python-ipopt? 要安装 python-ipopt,你需要先安装 Ipopt 库。这个库是用 C 编写的,所以你还需要安装一些 C 编译器。 在 Linux 系统上,你可以使用下面的命令来安装 Ipopt 和相关的依赖项: 复制 sudo apt-g…

excel成本统计:如何进行区域筛选,多条件求和?

最近有位小伙伴被一个计算产品成本的问题难住了,要求是根据配件成本核算出成品的成本。这个问题看上去似乎有点复杂,感觉一下子想不出好的解决办法,实际上,却非常简单,而且仅用常见的求和函数,就能轻松解决…

Mybatis源码分析(四)Mapper文件的解析

目录一 Mapper的使用二 MapperElement的解析三 解析cache-ref节点四 解析Cache节点五 解析ParameterMap节点六 解析ResultMap节点七 解析Sql节点八 处理各个数据库操作语句官网:mybatis – MyBatis 3 | 简介 参考书籍:《通用源码阅读指导书:M…

【每日一题】【LeetCode】【第一天】三数之和

三数之和的解决之路 题干表述 测试案列(部分) 第一次思路 这种其实是最暴力的,也是我脑海里第一个想到的最简单的方法了。 思路就是三个循环,一个循环去一个数,然后当三个下标不同,且对应的三个数相加为…

FPGA设计CPU书籍

一直以来CPU内部是绝大多数IT工程师难以触及的领域。纵使学习过计算机架构相关课程,自己动手实现CPU也始终遥不可及,因为这涉及计算机系统的最底层——芯片设计。 而近年来FPGA芯片产品的发展与普及打破了这一阻碍,利用内部电路可重编程的FPG…

【C++进阶】IO流

🎇C学习历程:入门 博客主页:一起去看日落吗持续分享博主的C学习历程博主的能力有限,出现错误希望大家不吝赐教分享给大家一句我很喜欢的话: 也许你现在做的事情,暂时看不到成果,但不要忘记&…

Docker进阶(中)

docker 进阶(中)docker提交镜像等命令docker 镜像原理docker 私有库&推送到私有库容器数据卷docker 安装常规软件docker提交镜像等命令 再这个谈这个docker 提交这个镜像之前我们先补充一下上一篇博客没有谈到的命令。再这里说一下。我们之前谈到的…

代码随想录算法训练营第六天 java :242.有效的字母异位词 349. 两个数组的交集 ,1. 两数之和

文章目录哈希表理论基础哈希碰撞: 拉链法和线性探测法线性探测法Leetcode242.有效的字母异位词题目链接思路AC代码Leetcode349. 两个数组的交集题目链接思路AC代码Leetcode 1. 两数之和题目链接思路与难点AC代码收获今日收获哈希表理论基础 哈希函数如下图所示&…

【C++】string (上)(string类的常用接口 string类对象的容量操作 string类对象的访问及遍历操作 string类对象的修改操作)

文章目录string标准库中的string类string类的常用接口string类对象的容量操作string类对象的访问及遍历操作string类对象的修改操作string string是一个专门管理字符数组的类。 标准库中的string类 string是表示字符串的字符串类该类的接口与常规容器的接口基本相同&#xff0…

计算机二级python考前复习笔记

Python是一种解释型、面向对象、动态数据类型的高级程序设计语言程序设计风格:清晰第一,效率第二。结构化程序设计原则:自顶向下,逐步求精,模块化,限制使用goto语句(Python无 goto 语句&#xf…

【回答问题】ChatGPT上线了!SLAM有哪些模型实现代码/案例/github源码?推荐10个以上比较好的SLAM深度学习模型?

目录SLAM有哪些模型实现代码?SLAM有哪些模型实现案例?SLAM有哪些模型的github源码?推荐10个以上比较好的SLAM深度学习模型?推荐10个以上比较好的SLAM深度学习模型github源码?SLAM有哪些模型实现代码? SLAM…

阿里云云数据库RDS的基本使用(二十三)

文章目录1.查看RDS数据库的基本信息2.查看RDS数据库的连接地址3.创建数据库账号并配置白名单3.1.创建数据库连接账号3.2.将ECS服务器添加到RDS白名单3.3.在ECS中登陆RDS数据库4.查看RDS数据库的监控5.查看RDS服务可用性6.查看RDS数据库的日志在RDS实例列表中点击管理即可跳转到…

ubuntu20驱动双屏问题总结

一、环境 设备:拯救者R7000P 显卡:NVIDA GeForce RTX 2060 系统:windows10ubuntu20的双系统下 显示器:笔记本显示器arzopa便携式显示器(使用的type-c接口) 驱动:nvidia-driver-520 二、问题…

【GO】K8s 管理系统项目[API部分--Service]

K8s 管理系统项目[API部分–Service] 1. 接口实现 service/dataselector.go // service type serviceCell corev1.Servicefunc(s serviceCell) GetCreation() time.Time {return s.CreationTimestamp.Time }func(s serviceCell) GetName() string {return s.Name }2. servic…

【C++】-- 海量数据处理

目录 位图 位图概念的引入 位图的实现 实现功能 开辟bit空间 数据输入set 数据删除reset 数据确认test 代码汇总 容器位图的衍生使用 布隆过滤器 布隆过滤器提出 布隆过滤器概念 ​布隆过滤器的实现 布隆过滤器的删除 布隆过滤器的特点 ​布隆过滤器的误判率 …

【电动车】基于削峰填谷的电动汽车多目标优化调度策略研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…