目录
多态具备的三个条件:
1.继承
2.重写
3.向上转型,父类的对象保存子类的实例,父类的引用指向子类的对象
多态的基础语法:
1.学习多态基础语法之前,我们需要普及两个概念:
第一个:向上转型
子----->父(比喻:自动类型转型)
父类类型 变量名 = new 子类类型();
如:Animal a = new Cat();
第二个:向下转型
父------>子(比喻:强制类型转换,需要加强制类型转换符)
子类类型 变量名 = (子类类型) 父类变量名;
如:Cat c =(Cat) a;
注意:
java中允许向上转型,也允许向下转型。
无论是向上转型,还是向下转型,两种类型之间必须有继承关系,没有继承关系编译器报错。
自动类型转换和强制类型转换是使用在基本数据类型方面的,
在引用类型转换这里只有向上和向下转型。
通过向上转型对多态了解
无论是向上还是向下转型,两种类型之间必须要有继承关系,这是首要条件,没有继承关系,就没有向上和向下转型。
没有继承关系的两个类型之间不存在转型!
什么是多态?
类在强制类型转换过程中,如果是类转换成接口类型,那么类和接口之间不需要存在继承关系,也可以转换,java语法中允许。
多种形态,多种状态,编译和运行有两个不同的状态。
编译期叫做静态绑定。
运行期叫做动态绑定。
多态的典型代码:父类型的引用指向子类型的对象(java中允许这样写代码)
例子:Animal a = new cat();
编译阶段:(静态绑定)
对于编译器来说,编译器只知道a的类型是Animal,所以编译器再检查语法的时候,会去Animal.class的字节码文件中找move()方法,找到了,绑定move()方法,编译通过,静态绑定成功。
运行阶段:(动态绑定)
运行阶段,实际上再堆内存中创建的java对象是cat对象,所以参与move()对象的是一直猫 ,所以运行阶段会动态执行cat对象中的move方法,这个过程属于运行阶段绑定。
多态指的是:多种形态
父类型引用指向子类型对象,
包括编译阶段和运行阶段:
编译阶段:绑定父类的方法
运行阶段:动态绑定子类型对象的方法。
分析程序一定要分析编译阶段的静态绑定和运行阶段的动态绑定
只有编译通过的代码才能运行,没有编译,根本轮不到运行。
java中只有"类名"或者"引用"才能去用到“点”
类名.
引用.
向下转型
父----->子(downcasting)
又被称为强制类型转换:需要添加强制类型转换符(instanceof)
什么时候必须使用“向下转型”?
当你需要访问的是子类对象“特有”的方法,此时必须进行向下转型。
向下转型有风险吗?
容易出现按ClassCastException(类型转换异常)
怎么避免风险?
instanceof运算符,可以再程序运行阶段动态的判断某个引用指向的对象。是否为某一种类型。
向下转型之前一定要使用instanceof运算符进行判断。
不管是向上转型还是向下转型,首先他们之间必须有继承关系,这样编译器就不会报错。
向下转型案例:(要运行子类特有的方法:猫抓老鼠)
public class Animal{
public void move(){
System.out.println("动物在移动");
}
}
public class Cat extends Animal{
public void move(){ //重写move方法
System.out.println("猫在走猫步");
}
public void move2(){ //子类特有的方法
System.out.println("猫会抓老鼠");
}
}
public class AnimalTest{
public static void main(String[] args){
Animal a = new Cat();
Cat c = (Cat) a;
c.move2(); //猫会抓老鼠
}
}
第二种方法用 instanceof运算符
1.instanceof可以在运行阶段动态判断引用指向的对象的类型。
2.语法:
(引用 instanceof 要调用方法的类名)
3.instanceof运算符的运算结果只能是:true/false
4.假设:c是一个引用,c变量保存了内存地址指向了堆中的对象。
(c instanceof Cat)为true表示:
c引用指向堆内存种java对象是一个cat。
(c instanceof Cat)为false表示:
c引用指向的堆内存种java对象不是一个cat。
向下转型一定要使用instanceof这样才能可以避免类型转换异常
public class AnimalTest{
public static void main(String[] args){
Animal a = new Cat();
if(a instanceof Cat){ //如果a是一个猫
Cat c = (Cat) a; //再进行强制类型转换
c.move2(); //猫抓老鼠
}
}
}
多态在开发中有什么用?
降低程序的耦合度,提高代码的扩展力。
面向对象的三大特征:
封装、继承、多态 一环扣一环
有了封装,才有了这种整体的概念之后。
对象和对象之间产生了继承。
有个继承之后,才有了方法的覆盖和多态。
这里涉及到一个软件的开发原则:
软件开发原则有七大原则(不属于java,这个开发原则属于整个软件业):
其中有一条最基本的原则:ocp(开闭原则)
什么是开闭原则?
对扩展开放(你可以额外添加,没问题),对修改关闭(最好很少的修改现有程序)
对软件的扩展过程中,修改的越少越好
高手开发项目不仅仅是为了实现客户的需求,还需要考虑软件的扩展性。
什么是软件扩展性?
假设电脑的内存条坏了,我们可以买一个新的插上,直接使用。
这个电脑的设计就考虑了“扩展性”。内存条的扩展性很好。
一定要记住:软件在扩展过程当中,修改的越少越好。
修改的越多,你的系统当前的稳定性就越差,未知的风险就越多。