1.关于A b = new B(),B是A的子类,调用b.eat()是怎么运作的?
答:编译时根据左边部分来编译,即根据类A来编译,若A有eat()方法,则编译通过,若A没有eat()方法,则编译失败。运行时具体是调用A的eat()方法,还是调用B的eat()方法,则根据静态绑定或动态绑定来判断,若是静态绑定,则编译时就确定了是调用A的eat()方法,若是动态绑定,则在运行时才能确定,若B有eat()方法,则调用B的eat()方法,若B没有eat()方法,则调用A的eat()方法。
2.只有动态绑定体现了多态,静态绑定是没有体现多态的。
3.private方法、static方法、final方法是静态绑定的,其他则是动态绑定。
4.静态绑定:指编译的时候就知道调用的是父类还是子类的方法。如A、B类,B类是A的子类,A、B类都有static的chi()方法,A b = new B(),调用b.chi(),编译的时候会检查A类是否有chi()方法,有则编译通过,没有则编译不通过。如果编译通过了,因为static是静态绑定的,所以JVM知道b.chi()是调用的A类的chi()方法,编译的时候就确定了调用的是A类的chi()方法,然后运行的时候就会调用A类的chi()方法;
5.动态绑定:编译的时候是不知道调用父类还是子类的方法,运行的时候才能确定。如A b = new B(),调用b.eat(),B是A的子类,eat()方法是public的成员方法,编译是根据左边部分编译的,编译会先检查A类是否有eat()方法,有则编译通过,没有则编译不通过。如果编译通过了,然后运行的时候是根据右边部分来的,会检查B类是否有eat()方法,有则调用B类的eat()方法,没有则调用A类的eat()方法。
6.为什么静态方法不能重写?
首先我们要知道重写的目的是什么,重写的目的就是为了实现多态,使一个类的不同的对象在某个方法上展现出不同的行为,明白了这个之后,我们再看看什么是静态方法,主要用静态方法来干什么,毋庸置疑,静态方法是属于一个类的,它就是被用来当作一个类的工具方法,它属于这个类的所有对象,它是一个公用的方法,任何对象都可以使用它,任何对象都有这个共有的行为,所以静态方法不需要在不同的对象上有不同的行为,因此,从设计的角度看,它就不需要多态,也就是不需要重写,因此,它就被规定不能被重写。
这也能解释为什么把static方法设计成静态绑定。
7.为什么静态方法能被继承?
从第6条,我们知道static方法就是一个所有对象公用的一个工具类,既然父类有该工具方法,那么子承父业,子类自然也可有该工具方法,子类的所有对象都可使用该工具方法(子类的所有对象都具有该共有的行为)。
8.为什么声明的父类引用变量指向子类对象时无法调用子类特有的方法?
举个例子就知道了:
如A b = new B(),b.eat();B是A的子类,eat()是B特有的方法,A类没有,编译的时候是根据左边部分编译的,编译时JVM会检查A类是否有eat()方法,显然A类是没有eat()方法的,所以,编译就无法通过,自然无法调用子类特有的方法。
9.有类A,B,B是A子类,两个类中都有一个私有的成员方法eat(),且两个类中的eat方法一摸一样时,如A b = new B(),调用b.eat()是什么情况?
我们先来按正常思路想一下:那就是编译的时候是按左边部分编译的,那就是按A类编译的,会先检查A类是否有eat()方法,明显A类是有eat()方法的,所以编译通过,而且private方法是静态绑定的,所以在编译时期就确定了在运行的时候时调用A类的eat()方法,我们想当然就认为程序能正常运行,但是还有一点我们没有考虑到,那就是private表示方法只能在本类被调用,故结果是编译不通过。
10.private方法为什么是静态绑定的?
很简单,private是私有的,不能被继承,自然不能被重写,自然就没有多态,故设计成静态绑定的。
11.final方法为什么是静态绑定的?
也很简单,final表示不可变的,加在方法上,表示方法是不可变的,方法不可变,那就意味着方法不能被重写,进一步就可知道没有多态,自然就被设计成静态绑定了。