Java多态性中的静态绑定和动态绑定


绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来。对java来说,绑定分为静态绑定和动态绑定;或者叫做前期绑定和后期绑定。
静态绑定:
在程序执行前方法已经被绑定,针对java简单的可以理解为程序编译期的绑定;这里特别说明一点,java当中的方法只有final,static,private和构造方法是前期绑定(静态绑定)的。
动态绑定:
后期绑定:在运行时根据具体对象的类型进行绑定。
关于绑定相关的总结:
对于java当中的方法而言,除了final,static,private和构造方法是前期绑定外,其他的方法全部为动态绑定。
注意:在处理java类中的成员变量时,并不是采用运行时绑定,而是一般意义上的静态绑定。所以在向上转型的情况下,对象的方法可以找到子类,而对象的属性还是父类的属性。访问到的始终是父类的属性,如果想要访问子类的成员变量,最简单的办法是将该成员变量封装成方法getter形式。
代码如下:
public class Father {
protected String name = "父亲属性";
public String getName() {
return name;
}
public void method() {
System.out.println("父类方法,对象类型:" + this.getClass());
}
}
public class Son extends Father {
protected String name="儿子属性";
public String getName() {
return name;
}
public void method() {
System.out.println("子类方法,对象类型:" + this.getClass());
}
public static void main(String[] args) {
Father sample = new Son();//向上转型
//sample.method();
System.out.println("调用的成员:"+sample.getName());
//System.out.println("调用的成员:"+sample.name);
}
}
结果:调用的是儿子的属性。
注意:虽然父类中已经有了getName()方法,且子类可以继承这个方法,但是如果在子类中不覆盖这个方法(重新定义这个方法,尽管内容没变),那么上面程序返回的结果将还是"父亲属性",这可能与Java对成员变量都是采用静态绑定有关。所以必须复写那个getter方法才能访问到子类自己的属性,不然无效。
但那个method方法则不然,如果在子类中覆盖了父类的method方法,那么sample.method()运行结果将是"子类方法,对象类型:class Son"
如果子类中不定义method方法(这时将继承父类的method方法),此时sample.method()运行结果将是"父类方法,对象类型:class Son"
结果都是class Son表明此时仍然是动态绑定,能识别出子类,这是由于getClass()方法是动态加载的缘故。注意上面两种情况的区别,成员变量都是静态绑定的(包括类变量)
澄清一点:
父类的static方法子类可以继承,也可以被覆盖。
但当多态情况下,使用的是静态绑定,始终调用的是父类的static方法(看上去就像子类中无法覆盖父类中的static方法一样),事实上static方法是可以覆盖的,如果用子类的对象(或者子类名)去调用这个static方法,返回的将是子类覆盖后的结果。同样即使子类不定义这个static方法,也可以用子类的对象(或者子类名)来访问继承自父类的static方法。
关于About
订阅与交流
回文章顶部,点“馋小乐快送”进行订阅(推荐)
搜号码:chanxiaolekuaisong或搜公众号“馋小乐快送”
小乐者:微信私号ID:sealine_123
查看评论 回复