目录
多态
有点抽象,得慢慢理解
1.多态的基础
多态建立在继承的基础之上
2.含义:
同一操作(父类的方法)在不同的类(子类)的对象身上有不同的结果(在这里应该就能看出来是利用了方法重写了)
3.向上转型和向下转型概述
向上转型(自动类型转换):父类的引用调用子类的方法:子类--->父类
向下转型(强制类型转换):父类的引用调用子类独有的方法:父类--->子类
目前为止可能这两个还是不够明确,父类的引用其实是指一个通过父类创建的变量会指向一块子类的空间,那么当我调用这个变量里面的方法的时候其实是调用的子类空间里的这个方法由于子类当中已经重写了这个方法,所以执行效果会因为子类的不同而产生不同的执行效果,在后面会有其他的介绍
4.多态的如何表现不同的行为:
通过方法重写来实现不同的子类有相同的方法名不同的方法体
5.编译时的状态:
编译的时候,在定义的“引用”对应的类(父类)当中,找到需要的方法,然后引用的这个类(父类)中有这个方法,就会编译成功,把需要的方法绑定到这个引用上,是静态绑定
6.运行时的状态:
在运行文件的时候,new 子类()会在内存空间中开辟一块内存空间并且把内存地址绑定给刚才创建出来的父类变量,这是运行期间的绑定,叫动态绑定
7.向上转型
向上转型就理解成把子类的对象这块空间,用父类的变量来表示,从某种意义上可以看作是把子类转成了父类,实际应用其实就是多个子类都重写了父类的某个方法,调用相同的父类方法的时候,不同的子类对象(已经向上转型了对象)执行这个方法的时候对应不同的效果。
一句话描述就是父类的引用指向子类的对象
public class Person{
private String name;
public Person(){
}
public Person(String name){
this.name = name;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void moveWay(){
System.out.println("正在移动");
}
}
public class DisabledPerson extends Person{
public DisabledPerson(){
}
public DisabledPerson(String name){
super(name);
}
@Override
public void moveWay(){
System.out.println("正在坐着轮椅走");
}
}
public class CommonPerson extends Person{
public CommonPerson(){
}
public CommonPerson(String name){
super(name);
}
@Override
public void moveWay(){
System.out.println("正在坐着跳着走");
}
}
public class Test{
public static void main(String[] args){
//此处就是父类的引用指向了子类的对象
Person a = new DisabledPerson("张三");
Person b = new CommonPerson("李四");
//然后都是通过父类变量调用方法,虽然这个方法是父类自己的但是在子类中重写了,那么指向子类的空间之后调用的这个方法实际上是重写之后的方法,这就是向上转型
a.moveWay();
b.moveWay();
}
}
执行结果:
正在坐着轮椅走
正在坐着跳着走
8.向下转型
需要调用子类特有的方法的时候,父类没有子类的方法需要进行向下转型,把父类的引用转成子类的引用,但是前提是这个父类的引用必须本身就指向一块子类的空间
说白了其实就是,想要向下转型前提是,这个父类变量本身指向的就是个子类
语法 : (子类的类型)父类的引用
向下转型是有风险的(类比于强制类型转换数据类型)报错结果为ClassCastException
对于这种异常如何解决:
使用 instanceof运算符
这个是用于比较一个引用是不是属于一个类型的
语法就是(引用 instanceof 类型),返回值是布尔类型
public class Person{
private String name;
public Person(){
}
public Person(String name){
this.name = name;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void moveWay(){
System.out.println("正在移动");
}
}
public class DisabledPerson extends Person{
public DisabledPerson(){
}
public DisabledPerson(String name){
super(name);
}
@Override
public void moveWay(){
System.out.println("正在被人用轮椅推着走");
}
//子类残疾人独有的方法
public void disabledAbility(){
System.out.println("正在利用轮椅疾行");
}
}
public class CommonPerson extends Person{
public CommonPerson(){
}
public CommonPerson(String name){
super(name);
}
@Override
public void moveWay(){
System.out.println("正在坐着跳着走");
}
//子类身体正常的人独有的方法
public void commonAbility(){
System.out.println("这个人会唱,跳,rap,篮球");
}
}
public class Test{
public static void main(String[] args){
//此处就是父类的引用指向了子类的对象(向上转型)
Person a = new DisabledPerson("张三");
Person b = new CommonPerson("李四");
//然后都是通过父类变量调用方法,虽然这个方法是父类自己的但是在子类中重写了,那么指向子类的空间之后调用的这个方法实际上是重写之后的方法,这就是向上转型
System.out.print(a.getName());
a.moveWay();
System.out.print(b.getName());
b.moveWay();
//下面是向下转型的内容
System.out.print(a.getName());
//此处需要一个子类的引用来接受a向下转型的结果
if(a instanceof DisabledPerson){
DisabledPerson aa = (DisabledPerson)a;
aa.disabledAbility();
}
System.out.print(b.getName());
//此处需要一个子类的引用来接受a向下转型的结果
if(b instanceof CommonPerson){
CommonPerson bb = (CommonPerson)b;
bb.commonAbility();
}
}
}
执行结果:
张三正在坐着轮椅走
李四正在坐着跳着走
张三正在利用轮椅疾行
李四这个人会唱,跳,rap,篮球
当子类当中的方法是父类当中没有的时候就该使用向下转型了
9.总结
不论向上转型还是向下转型,只要子类没有重写方法,执行效果就和父类一样