java基础知识——16.多态
Posted L纸鸢
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java基础知识——16.多态相关的知识,希望对你有一定的参考价值。
这篇文章,我们来介绍一下java的多态
目录
1.多态概述
我们先来回顾一下前面的知识
利用封装,我们可以将一些零散变量和方法包装起来,这样要用时就直接利用对象来调用里面的变量和方法。而当我们的对象原来越多的时候,有些代码就会重复,所以,我们将这些重复的代码提取出来,封装成一个类,叫做父类,然后其余的类继承它,这就是继承。
那什么时候用到多态呢?
我们可以思考下面这样的一个场景。我们有一个学生管理系统,里面有老师,学生,管理员三种类型的User;我们有一个注册功能,就是一个方法,我们需要给这个方法传一个参数,请问,传什么参数??老师?那只能实现老师注册;学生?那也只能实现学生注册;有人说,我们可以写三个方法啊,麻烦吗?很麻烦。那如果我再增加一个角色:辅导员,你是不是也要写一个辅导员的方法?很显然,这是不现实的。
怎么办呢?用多态!就是创建这些User类型的共同父类,这样不管来什么对象都可以接收。
什么是多态?
同种类型的对象,表现出的不同形态
解释:
对象,我们知道,new出来的;表现形态,就是引用,不同的表现形态,就是不同的引用;也就是说同一种的对象,它可以赋值给不同的引用
多态的表现形式:
父类类型 对象名称 = new 子类对象;
多态的前提:
- 有继承或实现关系
- 有父类引用指向子类对象 (Fu f = new Zi() )
- 有方法的重写
多态的好处:
- 使用父类型作为参数可以接收所有子类对象
- 体现多态的扩展性和遍历
说点题外话:
- 什么是引用?就单纯的面对对象而已,引用就是你的对象名,对,对象名仅仅是个引用,实体是你new出来的对象。对象名只是方便对对象的引用
- 什么是对象?new出来的东西
- 那多态到底咋用?其实说白了,就是给你的对象换一个类型的名称而已,只不过换的时候有些要求(即多态的前提),但是它实质是还是你new出来的那个对象,因为它堆内存中存的还是你new出来的对象,我们不管它是啥类型,我们只管它的本质是啥
2.多态调用成员的特点
下面,我们来看一下java中多态调用成员的特点
口诀:
变量调用:编译看左边,运行也看左边
方法调用:编译看左边,运行看右边
下面,我们根据代码来看一下:
具体的分析在上面的注释中都写了。
其实还是要理解继承。继承是子类继承了父类的方法和成员,意思就是父类中有的子类中也有(不考虑权限修饰符),而我们调用出来的时候,是怎么区分的呢?根据引用的类型来区分的。同理,前面讲继承的时候也说过,子类重写父类的方法会覆盖掉父类原有的方法(在虚方法表中),这样一想,就更好的理解多态的调用了。
3.多态的优势与弊端
多态的优势:
- 在多态形式下,右边对象可以实现解耦合,便于扩展和维护
- 定义方法的时候,使用父类型作为参数,可以接收所有子类对象,体现多态的扩展性与便利
对1的解释:
Person p = new Student();
p.work; //业务逻辑发生改变时,后续代码无需修改
现在我们的代码是这个,第二天,我想让老师工作,那就只需要把 new Student( )改为 new Teacher( )就行,其余的无需修改。但是,如果你写的是Student s = new Student(),那么你后面就需要修改很多处,因为后面的所有对象都是Student类型的,也只能调用Student的方法。
对2的解释:
看一下代码:
如果不想用Object也行,那就写8个方法,对应8中类型吧
多态的弊端:不能使用子类中特有的功能
如下图所示:
解决方案:类型转换
如下图所示:
引用数据类型的类型转换的方式:自动类型转换,强制类型转换
强转解决的问题:
- 可以转换为真正的子类类型,从而调用子类独有的功能
- 转换类型和真实对象类型不一致会报错
- 转换的时候用 instanceof 关键字进行判断
4.instanceof 关键字
instanceof 是 Java 的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型。
instanceof
instanceof是Java中的二元运算符,左边是对象,右边是类;当对象是右边类或子类所创建对象时,返回true;否则,返回false。
这里说明下:
- 类的实例包含本身的实例,以及所有直接或间接子类的实例
- instanceof左边显式声明的类型与右边操作元必须是同种类或存在继承关系,也就是说需要位于同一个继承树,否则会编译错误
instanceof用法
1.左边的对象实例不能是基础数据类型
2.左边的对象实例和右边的类不在同一个继承树上
3. null用instanceof跟任何类型比较时都是false
代码示例:
public interface A
public class B implements A
public class C extends B
测试代码示例:
public class InstanceofTest3
public static void main(String[] args)
A a = null;
B b = null;
boolean result;
result = a instanceof A;
System.out.println(result); // 结果:false null用instanceof跟任何类型比较时都是false
result = b instanceof B;
System.out.println(result); // 结果:false null用instanceof跟任何类型比较时都是false
a = new B();
b = new B();
result = a instanceof A;
System.out.println(result); // 结果:true a是接口A的实例对象引用指向子类类B,类B实现了接口A,所以属于同一个继承树分支
result = a instanceof B;
System.out.println(result); // 结果:true a是接口A的实例对象引用指向子类类B,类B实现了接口A,所以属于同一个继承树分支
result = b instanceof A;
System.out.println(result);// 结果:true b是类B的实例对象,类B实现了接口A,所以属于同一个继承树分支
result = b instanceof B;
System.out.println(result);// 结果:true b是类B的实例对象,类B实现了接口A,所以属于同一个继承树分支
B b2 = new C();
result = b2 instanceof A;
System.out.println(result); // 结果:true b2是父类B引用指向子类C,类B实现了接口A,所以属于同一个继承树分支
result = b2 instanceof B;
System.out.println(result); // 结果:true b2是父类B引用指向子类C,所以属于同一个继承树分支
result = b2 instanceof C;
System.out.println(result); // 结果:true b2是父类B引用指向子类C,所以属于同一个继承树分支
instanceof应用场景
instanceof一般用于对象类型强制转换
public class C extends B
private void print(Object a)
System.out.println(a+" instanceof");
public void convert(String b)
if (b instanceof Object)
this.print(b);
public class InstanceofTest4
public static void main(String[] args)
C c = new C();
c.convert("aa");
输出结果:
aa instanceof
5.小结
这篇文章,我们主要介绍了多态,一句话:父类引用指向子类对象。话很短,但包含的信息很多,要理解。除了多态,我们还介绍了一下java中的 instanceof 关键字,也是很简单的用法。
[Java基础]多态基础
多态:
以上是关于java基础知识——16.多态的主要内容,如果未能解决你的问题,请参考以下文章