多态
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