多态

package testMap;

public class Cf {

    int i;
    public Cf(){
        add(1);
    }
    void add(int v){
        i = i+v;
        System.out.println("father add "+i);
    }
}

 

package testMap;

public class Cs extends Cf {

    public static void main(String []args){
        new Cs();
    }
    public Cs(){
        add(2);
    }
    void add(int v){
        i = i+v*2;
        System.out.println("son add:"+i);
    }


}

上面代码输出的是:

son add:2
son add:6

 

正常情况下,如果通过多态将父类型的引用指向子对象地址,调用某个被覆盖的方法时,这时调用到的就是子类定义的方法。

public class Father{
   public void say(){
    System.out.println("father say:")
  }

}

public class Son extends Father{

  public void say(){
    System.out.printlin("son say")
  }

public static void main(String args[]){
    Father f = new Son();
    s.say()// son say
  }
}

 

 

上面代码中,实例化的是子类对象,但是在子类实例化之前,会先实例化父类

原因:

在《深入理解java虚拟机》中是这样描述的:

invokevirtual指令的多态查找,分为以下几个步骤

1、找到操作数栈定的第一个元素所指向的对象的实际类型,记为C.

2、如果在类型C中,找到常量中的描述符合简单名称都相符合的方法,则进行权限访问限制校验,如果通过,则返回这个方法的直接引用,查找结束

3、否则按照继承关系从下往上对C的各个父类进行第2步的搜索和验证过程

4、如果始终没有找到合适的方法,则爆出java.lang.AbstractMethodError异常。

 

所以最开头的代码,如果将变量和方法都声明为static,

则会输出结果:

father add 1
son add:5

posted @ 2019-11-17 16:56  sliec  阅读(104)  评论(0编辑  收藏  举报