Java的多态(静态绑定和动态绑定)

参考资料:http://blog.csdn.net/lingzhm/article/details/44116091


java多态具体表现形式有两种:方法的重写和方法的重载。先来看一段程序(此段代码摘自上述链接中):

public class Main {
    public static void main(String[] args) {
        Base b=new Base();
        Derived d=new Derived();
        whichFoo(b, b);
        whichFoo(b, d);
        whichFoo(d, b);
        whichFoo(d, d);
    }
    public static void whichFoo(Base arg1,Base arg2){
        arg1.foo(arg2);
    }
}
class Base{
    public void foo(Base x){
        System.out.println("Base.Base");
    }
    public void foo(Derived x){
        System.out.println("Base.Derived");
    }
}
class Derived extends Base{
    public void foo(Base x){
        System.out.println("Derived.Base");
    }
    public void foo(Derived x){
        System.out.println("Derived.Derived");
    }
}

它的输出结果是:

Base.Base
Base.Base
Derived.Base
Derived.Base

这是因为在Java中,一个方法的参数在编译阶段常被静态地绑定,在whichFoo方法中,形式参数arg2的类型是Base, 因此不管arg2实际引用的是什么类型,arg1.foo(arg2)匹配的foo都将是foo(Base),而要知道arg1引用的对象时,这是在运行阶段由JVM决定的,称为动态绑定。

再来看下面一段程序:

public class Main {
    public static void main(String[] args) {
        Father father=new Son();
        System.out.println(father.age);
        father.name();
        father.age();
    }
}
class Father{
    public int age = 60;
    public static void name(){
        System.out.println("father name");
    }
    public void age(){
        System.out.println("father age:"+age);
    }
}
class Son extends Father{
    public int age = 25;
    public static void name(){
        System.out.println("son name");
    }
    public void age(){
        System.out.println("Son age:"+age);
    }
}

输出结果为:

60
father name
Son age:25

解释如下:
当执行 Father father=new Son();发生了向上转型,在编译期间 father就是个Father对象,系统不知道实际上它是一个 Son对象,这得在运行期间由JVM判断

在我们调用father.age的时候实际上,在处理java类中的成员变量时,并不是采用运行时绑定,而是一般意义上的静态绑定,即调用的是Father类的age成员变量

在调用father.name()的时候,注意这是个static方法,java当中的方法final,static,private和构造方法是前期绑定,因此调用的是Father类中的name方法

在调用father.age()的时候,需要采用动态绑定,此时father会被解析成它实际的对象,即Son对象,因此实际调用的是Son.age()

阅读更多
换一批

没有更多推荐了,返回首页