用最少的字、简明且易懂的文章来简单说明:java运行时的多态
前言
最近在复习面试题目,发现网上找的java多态文章,有的复杂,有的乱,而且有的没说清楚,自己看了很多篇之后,以最少的文字、简介且易懂的文章将它说明白。
定义
一个被定义的引用变量指向哪个类的实体对象、该变量调用的方法具体是属于哪个类的在编译的时候是不知道的,只有在程序运行时才能知道前面两个问题的答案;这样就可以在不修改源码的情况下,根据要求将引用变量指向不同的类,从而可以改变程序的运行状态,这就是多态。
实现多态的必要条件(基于继承实现的多态也叫运行时的多态)
- 有继承:存在父类和子类
- 有重写:子类重写了父类的某个方法
- 有向上转型:子类的实例对象赋值给了父类类型的引用变量:
//假设A类是B的父类,
A a = new B( ); //这就是向上转型
向上转型的特点
- 父类引用只能访问父类的方法和属性。
- 如果子类重写了父类的方法A,那么父类引用调用方法A时,表面上是调用了父类自己的方法A,实际上调用的是子类的方法A,而且实际效果就是子类的方法A的执行效果。
多态的典例(基于继承实现的多态)
- 基于继承实现的多态:有父类A,子类B,子类B重写了父类A的方法Add;创建一个B的实例赋值给类型为A的引用变量,即A a = new B( );
a调用Add方法,会发现Add方法执行的效果其实是子类B里重写的Add方法的执行效果,这就是多态的表现。
方法调用优先级
必须明确两点:
- 下面的this指new的是哪个类,就指的是哪个类的实例对象。如:A a = new B( ) 那么这里的this指的就是B类型的实例对象。
- super指的是找到其直接父类。
- 方法调用优先级:this.show(obj) > super.show(obj) > this.show((super)obj) >super.show((super)obj)
可能看完这里,你还不太懂得这个优先级怎么用,那么下面以具体代码给大家讲解。
多态典例(以代码讲解,并附带讲解方法优先级如何使用)
- 创建四个类A、B、C、D。
- 利用向上转型体现多态
代码
public class A {
public String show(A obj){
return "A and A";
}
public String show(C obj){
return "A and C";
}
public String show(D obj){
return "A and D";
}
}
******************************************
public class B extends A{
public String show(A obj){
return "B and A";
}
public String show(B obj){
return "B and B";
}
public String show(C obj){
return "B and C";
}
}
******************************************
public class C extends B{
}
******************************************
public class D extends B{
}```
******************************************
public class TestPolymorphism {
@Test
public void run1(){
A a2 = new B();
B b = new B();
C c = new C();
D d = new D();
//1、2、3就用到了方法的优先级
System.out.println("1、" + a2.show(b));
System.out.println("2、" + a2.show(c));
System.out.println("3、" + a2.show(d));
}
}
结果
讲解
讲解前必须明确一点:这个例子中,this指的是类B的实例对象,如果this调用了类B有的方法,而类A中没有的话,是会直接跳过的,就会往方法的下一优先级找。
- a2.show(b) 的执行:
根据第一优先级:this.show(obj),this指的是类B的实例对象,所以先去类B中找有没有方法show(B obj),发现有,但必须注意,此时引用变量类型是A,所以还要去类A中找有没有方法show(B obj),如果有,那么这行代码的执行结果就是执行类B的方法show(B obj);如果没有,则跳过去找下一优先级。此处会发现没有,那么下一优先级是:super.show(obj),发现类B的父类就是类A,没有方法show(B obj)。那么再跳到下一优先级:this.show((super)obj),发现要找的是类B的方法show(A obj),去类B的父类A中找,也有方法show(A obj),但此时要注意,show(A obj)的执行效果一定是子类类B的方法show(A obj)执行效果, 所以结果为: “1、B and A”。 - a2.show©的执行:
根据第一优先级:this.show(obj),this指的是类B,所以先到类B中找方法show(C obj),结果发现有,那么再去父类A中找有没有方法show(C obj),结果也发现有,那么该行代码的执行效果就是执行类B的方法show(C obj),所以结果为:“B and C”。 - a2.show(d)的执行:
以此类推。