疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java基础特性-多态-代码分析


 

       例子:

  Java代码

  class Father{

  public void func1(){

  func2();

  }

  //这是父类中的func2()方法,因为下面的子类中重写了该方法

  //所以在父类类型的引用中调用时,这个方法将不再有效

  //取而代之的是将调用子类中重写的func2()方法

  public void func2(){

  System.out.println("AAA");

  }

  }

  class Child extends Father{

  //func1(int i)是对func1()方法的一个重载

  //由于在父类中没有定义这个方法,所以它不能被父类类型的引用调用

  public void func1(int i){

  System.out.println("BBB");

  }

  //func2()重写了父类Father中的func2()方法

  //如果父类类型的引用中调用了func2()方法,那么必然是子类中重写的这个方法

  public void func2(){

  System.out.println("CCC");

  }

  }

  public class Test {

  public static void main(String[] args) {

  Father child = new Child();

  child.func1();//打印结果将会是什么?

  }

  }

  打印输出:

  “CCC”

  对于多态,可以总结它为:

  一、使用父类类型的引用指向子类的对象;

  二、该引用只能调用父类中定义的方法和变量;

  三、如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法;(动态连接、动态调用)

  四、变量不能被重写(覆盖),”重写“的概念只针对方法,如果在子类中”重写“了父类中的变量,那么在编译时会报错。

  代码:

  Java代码

  class A {

  public String show(D obj){

  return ("A and D");

  }

  public String show(A obj){

  return ("A and A");

  }

  }

  class B extends A {

  public String show(B obj){

  return ("B and B");

  }

  public String show(A obj){

  return ("B and A");

  }

  }

  class C extends B{}

  class D extends B{}

  A a1 = new A();

  A a2 = new B();

  B b = new B();

  C c = new C();

  D d = new D();

  System.out.println(a1.show(b));//(1)

  System.out.println(a1.show(c));//(2)

  System.out.println(a1.show(d));//(3)

  System.out.println(a2.show(b));//(4)

  System.out.println(a2.show(c));//(5)

  System.out.println(a2.show(d));//(6)

  System.out.println(b.show(b)); //(7)

  System.out.println(b.show(c));//(8)

  System.out.println(b.show(d));//(9)

  打印结果:

  A and A //(1)

  A and A //(2)

  A and D //(3)

  B and A //(4)

  B and A //(5)

  A and D //(6)

  B and B //(7)

  B and B //(8)

  A and D //(9)

  分析:

  实际上这里涉及方法调用的优先问题 ,优先级由高到低依次为:

  this.show(O)、

  super.show(O)、

  this.show((super)O)、

  super.show((super)O)。

  让我们来看看它是怎么工作的。

  比如(4),a2.show(b),a2是一个引用变量,类型为A,则this为a2,b是B的一个实例,于是它到类A里面找show(B obj)方法,没有找到,于是到A的super(超类)找,而A没有超类,因此转到第三优先级this.show((super)O),this仍然是a2,这里O为B,(super)O即(super)B即A,因此它到类A里面找show(A obj)的方法,类A有这个方法,但是由于a2引用的是类B的一个对象,B覆盖了A的show(A obj)方法,因此最终锁定到类B的show(A obj),输出为"B and A”。

  再比如(8),b.show(c),b是一个引用变量,类型为B,则this为b,c是C的一个实例,于是它到类B找show(C obj)方法,没有找到,转而到B的超类A里面找,A里面也没有,因此也转到第三优先级this.show((super)O),this为b,O为C,(super)O即(super)C即B,因此它到B里面找show(B obj)方法,找到了,由于b引用的是类B的一个对象,因此直接锁定到类B的show(B obj),输出为"B and B”。