Java中的类和对象(4)

1.多态

完成某个行为时,不同的对象去完成就会产生不同的状态,就叫做多态。概念比较抽象,举个例子,动物都有吃饭的行为,但是猫咪完成吃饭的动作,就会表现为吃猫粮的状态,小狗完成吃饭的行为,就会表现为吃狗粮的状态,大熊猫完成吃饭的动作就会表现为吃竹子的状态。同样都是吃饭的动作,不同动物吃饭,表现出来的状态是不一样的,这就是多态。

2.向上转型和向下转型

想要了解多态,我们必须要先了解向上转型和向下转型。

向上转型:创建一个子类对象,将其当成父类对象来使用。具体在代码中是如何体现的呢?如下图:

上图所示就是向上转型。

大家可能会疑惑,为什么创建的子类对象可以赋值给父类对象?原因是子类是源于父类的,小狗类和熊猫类都源于动物类,只是多了一些自己独有的属性和方法,但是它还是动物类的一种,因此创建的子类对象可以赋值给父类。但是这样做会产生一些缺陷,赋值给父类的子类对象,将无法调用子类独有的实例属性和实例方法,如下图:

因此我们可以知道,当发生向上转型时,赋值给父类的子类对象将无法调用子类独有的实例方法,实例属性也同理。

当然向上转型同样也具备能够让代码实现更加灵活的优点。

除了创建子类对象赋值给父类这种方式,还有另外两中方式:方法传参和方法返回,也能实现向上转型,如下图:

我们在动物类中定义了一个静态的玩耍方法,参数类型是Animal,我们创建了一个小狗实例对象d,在调用玩耍方法时,我们把小狗d传了进去,这样实际上也实现了向上转型。

再来看另剩下的一种,如下图:

当方法的返回值类型为Animal的时候,我们可以返回一个Dog类型的对象,这时候也发生了向上转型。

向下转型:

理解了向上转型,那我们再来看看向下转型。将一个子类对象经过向上转型之后,当成父类对象使用,再无法调用子类方法,但是有时候需要调用子类特有的方法。此时,再将父类对象还原为子类对象,就是向下转型。如下图:

我们先是将小鸟向上转型为Animal,可能经过一些列操作后,我们又想调用小鸟飞的方法,这时候就需要向下转型为原来的小鸟,才能再调用。如上图,向下转型后,调用成功,信息打印正确。

如果原本向上转型的不是小鸟,那么将不能向下转型为小鸟,如果强行转换,编译器会报错。如下图:

我们将小狗强行转换为小鸟,然后调用小鸟飞的方法,虽然语法也没有报错,但是运行的时候报转型异常。

因为上面这种情况,语法并不会报错提示,因此我们在进行向下转型时最好这样写代码:

使用关键字instanceof来判断是不是从小鸟转型来的,如果是可以调用飞方法,如果不是则提示"a2是从狗子转型过来的,不能飞"。

3.重写

了解完向上转型和向下转型之后,我们再学习一下重写的知识。重写是子类对父类非静态方法、非构造方法、非final修饰、非private修饰的方法外的方法进行重新实现的,并且实现时要求和父类方法返回值类型,方法名以及形参一致。例如:

父类里面定义了eatFood的方法,但是我们知道熊猫应该吃竹子,我们想写的具体一点,而不是笼统得写成吃饭,那么就需要对eatFood方法进行重写,方法得返回值,方法名以及参数列表都没发生变化,只有方法体发生了变化,这就是重写。

注意:需要注意的是,重写的方法子类的权限必须要大于等于父类的权限。因为在后面实现多态效果的时候,父类对象需要调用父类的方法,由于会发生动态绑定,实际上会调用子类重写的方法,那么子类方法的权限必须大于等于父类(public最大)方法的权限,否则编译器会报错,如下图:

注意:还需要注意返回值的类型,如果父类的方法的返回值类型和子类方法的返回值类型构成父子关系,那么可以不同,否则必须相同。如下图:

上图中如果Animal和Panda换位置,编译器则会报错。子类方法的返回值需要和父类保持一致,或者是父类方法返回值类型的子类。

4.动态绑定

也称为后期绑定(晚绑定),即在编译时,不能确定方法的行为,需要等到程序运行时,才能够

确定具体 调用那个类的方法。

编译时会编译父类的方法,实际调用时,会调用子类中重写的方法。这里仅演示一下动态绑定的效果,如下图:

按理说向上转型了就没法调用子类的方法了,但是这里居然调用了子类的方法!这就是向上转型的效果。程序在运行阶段会确定具体调用哪个类的方法,就是动态绑定。

5.多态实现的条件

说了向上转型,向下转型,方法重写以及动态绑定后,我们再来说回到多态。那么多态实现的条件是什么呢?如下:

a.必须在继承体系下(能够发生向上向下转型);

b.必须要对父类的方法进行重写;

c.通过父类的引用调用重写的方法(发生动态绑定);

我们再回忆一下多态的概念:当代码运行时,传递的不同的对象,会调用对应类中的方法,这就是多态的表现。

多态到这里就比较清晰了,也就是说不同子类对象定义重写方法后,可以通过调用父类对象的方法,发生动态绑定后产生的效果,就是多态。如下图:

小狗和熊猫重写了eatFood方法后,传递小狗和熊猫给Animal,都调用eatFood的方法,产生的结果却不同,小狗吃狗粮,熊猫吃竹子。

如果还有其它的动物,我们不知道它吃什么,或者它只能吃饭,我们只要不重写eatFood方法,那么它就还是可以保留吃饭的效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值