多态的初步认识

本文详细介绍了Java中的多态性概念,包括其目的、基础和实现方式。多态旨在降低耦合度,增强程序扩展性,主要依赖于向上转型和向下转型。通过实例解释了如何在运行时动态绑定方法并使用子类特有功能。同时,文章强调了使用instanceof关键字进行类型检查的重要性,以避免ClassCastException。最后,讨论了多态在代码设计中的优势,如提高代码复用性和遵循OCP原则。
摘要由CSDN通过智能技术生成

Java多态目的是:降低程序耦合度,提升程序扩展性,基础是向上转型(子->父,自动类型转换)和向下转型(强制类型转换,要加强制类型转换符)(引用方面最好说向上向下,自动和强制用在基本数据类型),但都需要有继承关系。

Animal  a= new Cat()//重写的方法
a.move()//输出猫走猫步,因为底层对象是一个猫。

父类型的引用允许指向子类型的对象,也就是多态的含义。
编译阶段,静态绑定父类的方法。
运行阶段,动态绑定子类型对象的方法。多种状态。

a.catchMouse;//子类特有方法

编译报错,因为编译阶段是静态,编译期在父类字节码文件中寻找catchmouse方法,但此方法只在子类中存在。假如可以过编译关的话,那么可以运行,但根本无法过编译语法关。

还想达成目的就要向下强制转换–目的就是使用子类特有方法。

Cat b =(Cat)a;
a.catchMouse()

编译通过

但是例如

Animal c = new Bird()Cat d = (Cat)c;

无法强制转换,因为编译器检测到c这个引用是animal类型,与cat存在继承关系,所以可以向下转型,可以编译,但在运行阶段,堆内存实际创建的是bird对象,无法将bird转化成cat,有类转化异常classcastexception导致无法运行。

How to avoid it?
利用instanceof符号来判断。
例如

if(c instanceof Cat){
Cat d = (Cat)c;
d.catchMouse();

表示如果c是一个Cat,再进行向下强制类型转换。instanceof符号可在运行时动态判断引用指向的对象的类型,并且只有true和false两种返回值。所以要保持向下转型时用instanceof运算符进行判断的习惯。
But,why?
因为当分工合作时,方法中用到的参数是Animal,然而参数并不由自己生成,我们无从得知Animal到底是Cat还是Bird,为了避免程序异常终止,我们只能人工预防。

回到开始,我们为什么用到多态?
假设一个场景,主人一开始养了一只狗,有feed方法。

public void feed(Dog dog){
dog.eat();
}

如果后来主人更换了宠物,就需要新增一个方法

public void feed(Cat cat){
Cat.eat();
}

不仅增加代码出错的概率,也不符合编写程序的规范–七大规范之一OCP,对扩展开放,对修改关闭。但如果我们事先编写一个Animal类 ,使Dog和Cat都继承自Animal。

pulic class Animal{
public void eat(){
}
public class Cat extends Animal{

}

这样,调用方法时代码就变成`

public void feed(Animal animal){//实际上是Animal animal = new Dog()/new Cat()
//编译器发现是Animal类,去Animal类中寻找eat方法,找到了运行就会通过,到了运行时会根据底层实际的对象类型自动调用到该类型的方法
animal.eat();

还有一个问题,为什么不直接把Pet定义成Object?接受万物?但如果定义为Object,就没有了eat方法,需要强制向下转型才能使用了,就是失去共同性,反而导致程序更加复杂。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值