JAVA面向对象之多态
2021/12/18 17:21:38
本文主要是介绍JAVA面向对象之多态,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
面向对象之多态
例子
class Person{} class Boy extends Person{} class Girl extends Person{}
一、多态的定义
生活上:
- 通俗的讲,就是同一个东西表现出多种状态
- 比如我开头的例子,男孩,女孩都是人类。是人类的不同状态
程序上:
- 父类引用指向子类的实例
- 同一个引用类型,使用不同的实例而执行不同操作
- 当我们使用父类的引用,指向子类的实例的时候,实际上就是一个向上转型的过程
我们一般在创建对象的时候
Boy boy = new Boy(); Girl girl = new Girl();
而多态的创建
//父类的引用指向子类的对象 //前面是父类声明 = 新建一个子类的对象 Person p = new Boy();
我们可以直接输出这个父类看一下
Person p = new Boy(); System.out.println(p);
运行结果:
Boy@2503dbd3
发现我们运行的时候识别到了它是Boy类
也就是说我们在编译前它被识别为父类,而编译后也就是运行的时候就被识别为子类了
这就是多态
在编译的时候创建父类引用指向子类的对象
而特性是运行的时候就已经是子类的对象了
二、为什么使用多态
我们来看这样一个场景
我们人都是要吃饭的,都有吃饭这个行为
class Person { public void eat(){ System.out.println("是人就得吃饭"); } }
虽然人都得吃饭,但是针对到男孩,女孩在吃饭上是有一定的差异的。
就需要重写一下父类的方法了
//男孩 class Boy extends Person{ public void eat(){ super.eat(); System.out.println("男孩要力气,得吃肉"); } } //女孩 class Girl extends Person{ public void eat() { super.eat(); System.out.println("女孩要苗条,得少吃"); } }
我们假设一个食堂类,食堂里是男孩,女孩吃饭的地方
class Canteen{ public void meal(Boy boy){ System.out.println("到食堂干饭"); boy.eat(); } public void meal(Girl girl){ System.out.println("到食堂干饭"); girl.eat(); } }
那么我们想要男孩,女孩都能进去吃饭,我们就需要进行重载,才能识别所有的参数
测试代码:
Canteen c = new Canteen(); Boy boy = new Boy(); c.meal(boy);
但是这样就会有一个问题
我们这里是只有男孩和女孩这两个类,重载了一次,代码开始有些重复了。
我们之前说过代码重复,我们就需要找到合适的方法解决重复的代码
为什么使用多态
- 为了解决重复代码
- 为了完善项目结构
三、如何实现多态
我们一开始说过,父类引用指向子类的对象是多态,该如何运用呢
Person p = new boy(); p.eat();
我们发现调用的是子类重写父类的方法
实际上多态的使用就这么简单
-
系统会自动进行类型转换
-
通过父类引用变量调用的方法是子类覆盖或继承的子类方法,不是父类的方法
-
通过父类引用变量无法调用子类特有的方法
1、通过方法参数
将我们参数从子类改为父类
代码如下
class Canteen{ public void meal(Person person){ System.out.println("到食堂干饭"); boy.eat(); } }
我们测试传参,测试代码不需要更改
Canteen c = new Canteen(); Boy boy = new Boy(); c.meal(boy); //测试的参数不需要改变
也是能够实现的,但是不需要重载
这个能够实现是因为形参Person person就是创建了一个父类的引用
当我们传参的时候,就是使父类指向了子类的对象
2、通过方法的返回值
这个就更简单了
我们先写一个方法
代码如下
public Person getPerson(String choose){ if(choose.equals("boy")){ return new Boy(); }else if(choose.equals("girl")){ return new Girl(); }else{ System.out.println("输入有误"); return null; } }
当我们调用该方法的时候,通过参数选择,返回男孩或者女孩。
返回的都是一个Person类型的,但是却是一个父类的引用指向子类的对象
四、注意点
1、转型问题
刚才说过,父类引用指向子类的对象,是向上转型。
//左边是父类 右边是子类 //和以前学习基础类型时候的默认强转很像 //int a = short Person p = new Boy();
有向上转型就有想下转向
//向下转型的注意点是:能被转为子类的父类,一定是父类引用指向子类的对象 //能转成功,也必须是父类指向的就是这个子类才行 //同样和基础类型的强转很像 //short a = (short)int Boy b =(Boy)p;
2、确保转型成功--instanceof
关键字
我们是已知当前这个对象是父类指向的某个子类
所以直接能够将父类向下转型为子类
但是我们可以看下面代码
Person p = new Boy(); Girl g = (girl)p;
运行之后就告诉我们,是没办法将Boy类转为Girl类
我们明显的发现一定需要转为对应的子类才能成功。
所以我们需要一些判断手段
boolean a = p instanceof Boy; //我们发现返回的是true
由此我们可以看出来
[对象名] instanceof [类]; //判断对象是否是该类的 //是返回true 否返回false
这样,我们就可以直接先判断再强转了
if(p instanceof Boy){ Boy b =(Boy)p; }
可保万无一失
3、为什么需要强转
我们本来今天就是为了使用父类引用子类的对象去操作,为什么还需要进行强转回去呢
我们发现,使用多态没有办法调用子类独有的方法,当我们需要调用子类独有的方法的时候,我们进行强转然后再调用
五、面向对象小结
面向对象的三大特性:封装、继承、多态
-
封装是隐藏对象的属性和实现细节
- 将类的成员属性声明为私有的,同时提供公有的方法实现对该成员属性的存取操作
-
继承是软件可重用性的一种表现
- 新类可以在不增加自身代码的情况下,通过从现有的类中继承其属性和方法充实自身内容
-
多态是具有表现多种形态的能力的特征
- 在程序设计的术语中,意味着一个特定类型的变量可以引用不同类型的对象,自动地调用引用的对象的方法
- 即根据作用到的不同对象类型,响应不同的操作
- 在程序设计的术语中,意味着一个特定类型的变量可以引用不同类型的对象,自动地调用引用的对象的方法
这篇关于JAVA面向对象之多态的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-07-04TiDB 资源管控的对撞测试以及最佳实践架构
- 2024-07-03万字长文聊聊Web3的组成架构
- 2024-07-02springboot项目无法注册到nacos-icode9专业技术文章分享
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现