关于多态
多态是面向对象的核心思想之一,多态的实现有三要素: 1、 存在继承 2、子类对父类的方法进行了重写 3、父类引用指向子类对象。
前面说的还是有点虚,下面通过一个例子来深入理解多态。
程序代码如下,给出对应的输出:
1 public class Polymorphism {
2 public static void main(String[] args) {
3 A a1 = new A();
4 A a2 = new B();
5 B b = new B();
6 C c = new C();
7 D d = new D();
8
9 a1.show(b);
10 a1.show(c);
11 a1.show(d);
12 a2.show(b);
13 a2.show(c);
14 a2.show(d);
15 b.show(b);
16 b.show(c);
17 b.show(d);
18 b.show(a1);
19 a1.show(a1);
20 a2.show(a1);
21 }
22 }
23
24 class A {
25 public void show(A a) {
26 System.out.println("A and A");
27 }
28
29 public void show(D d) {
30 System.out.println("A and D");
31 }
32 }
33
34 class B extends A {
35 public void show(B b) {
36 System.out.println("B and B");
37 }
38
39 public void show(A a) {
40 System.out.println("B and A");
41 }
42 }
43
44 class C extends B {
45 }
46
47 class D extends B {
48 }
下面我就来依次说说每一行的输出并给出为什么:
1. 对于a1.show(b) 因为a1的类型是A,所以只能调用A中的show(A a)方法 ----> 输出是 A and A
2. 对于a1.show(c) 理由同上 ------> 输出也是 A and A
3. 对于a1.show(d),此时a1的类型是A,但是此时因为传入的参数是D类型的,所以此时调用的是show(D d)方法 ----> 输出是A and D
4. 对于a2.show(b),此时a2是父类的引用指向子类的对象,虽然a2的实际类型是B,但是在方法调用上只能调用A的方法。所以此时调用的是A中的show(A a)方法,但是这时候又存在多态:A中的show(A a)在B中被重写了,所以此时实际调用的是B中的show(A a)方法。 -----> 输出是 B and A
5. 对于a2.show(c).理由同上 -----> 输出是 B and A
6. 对于a2.show(d).此时调用的是A中的show(D d)方法 ----->输出是 A and D
7. 对于b.show(b). 此时b是B类型对象,此时应该调用B中的show(B b)方法 ------> 输出是 B and B
8. 对于b.show(c). 理由同上 ------> 输出是 B and B
9. 对于b.show(d).此时B是B类型的对象,父类是可以调用子类中的方法,在方法调用的时候,会去找最匹配的方法,发现A中的show(D d)最匹配。 -----> 输出时 A and D
10. 对于b,show(a1). 此时最匹配的是B中的show(A a)方法 ------> 输出是 B and A
11. 对于a1.show(a1). 不用想直接调用的是A中的show(A a)方法 -----> 输出是 A and A
12. 对于a2.show(a1). 根据多态可得 ------> 输出是 B and A
- HDFS学习:HDFS机架感知与副本放置策略
- spring cloud 报错Error creating bean with name 'hystrixCommandAspect' ,解决方案
- Spring Security OAuth2 Demo
- SpringBoot学习:整合shiro(身份认证和权限认证),使用EhCache缓存
- 线性回归与最小二乘法 | 机器学习笔记
- 添加sqljdbc4的maven依赖
- MyBatis 实现关联表查询
- 数据结构 | 栈
- mybatis 针对SQL Server 的 主键id生成策略
- 算法 | 排序算法图形化比较:快速排序、插入排序、选择排序、冒泡排序
- WCF 添加 RESTful 支持,适用于 IIS、Winform、cmd 宿主
- 在CentOS 7上安装Nginx服务器
- 卷积神经网络 | 深度学习笔记1
- 【直播】我的基因组65:看看哪些基因的突变较多,哪些较少
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- android特卖列表倒计时卡顿问题的解决方法
- dotnet 多线程禁止同时调用相同的方法 禁止方法重入调用 双检锁的设计
- android实现倒计时功能(开始、暂停、0秒结束)
- 【-Flutter/Dart 语法补遗-】 sync* 和 async* 、yield 和yield* 、async 和 await
- android实现条目倒计时功能
- Android实现简单手电筒功能
- k8s安装自动证书签发cert-manager letsencrypt
- Android仿Keep运动休息倒计时圆形控件
- android通过led实现手电筒功能
- Android 7.0 手电筒控制实现
- 【STM32H7】第13章 RL-TCPnet V7.X之创建多个TCP客户端
- Android倒计时的开始与停止 剩余时分秒的展示
- 由LFI引起的Zimbra邮件管理系统0day
- Android手电筒兼容各个手机与版本
- 【STM32F429】第13章 RL-TCPnet V7.X之创建多个TCP客户端