建议core java2 vol I (中文) P115

解决方案 »

  1.   

    private 是干什么用的。书上没说。
      

  2.   

    如果方法为private,那么肯定是静态联编(编译时链接)。
    那么
    PolyB的方法g实际上在编译时就变成了
    public int g() {
        return 1;// 因为方法f()是私有的
    }相反,如果方法f是公有的,那么就是动态联编了(运行时链接)。
    这时候按照多态的原则,返回2也就很正常了。
      

  3.   

    也就是说static方法或private方法都是编译时绑定的?????
      

  4.   

    这是多态性中的覆盖方法问题,其中有这样一个原则:被应用的对象的类型(而不是句柄变量的类型)决定了执行哪个版本的覆盖方法。根据这一原则,在这段程序中,已经显式地将对象变量ref1转换为PolyB类类型,所以该程序将调用PolyB类中的覆盖方法。所以最后打印1.
      

  5.   

    是这样的:对static函数和private函数,JVM分别用invokestatic, invokespecial (bytecode指令)调用,这两者都是staticly bind. 
    每个class实例都会有一张method table,里面有所有父类中继承来的方法和自己重载的方法的指针(指向method area的实际代码).所以对于PolyA, PolyB, PolyC, method table分别为(省略从object继承来的):
    PolyA          PolyB                PolyC
    -------        -------------        -----------------------------------
    | g()  |      | g()(overide)|       |g() (从B继承来)                   |
    -------        -------------         ----------------------------------
                                        |f()(和A,B里面的private没有一点关系)|
                                        -----------------------------------
    ref1,ref2无论转换多复杂,实际还是安PolyC构造的,就当PolyC对待.
    这样说能明白了吗?
       
      

  6.   

    有理有理!哈哈哈哈哈  我叙述一下,大家看对不对,嘻嘻 - private方法不能被override
     - static方法可以被override
     - 但是这种对于static方法的override不能被“多态式后期绑定”(所以也就部份
       失去了override对于OO多态的意义)例子如下:
     - private方法不能被override
    class Father{
        private void m0() throws java.io.IOException {}
    }class Son extends Father{
        void m0() throws java.lang.Exception {}
    }
    这是可以编译的(注意这里子类掷出了“更宽”的异常,但是通过了编译)
    所以可以等效地认为这时子类中的m0()没有override父类中的m0()。 - static方法可以被override
    class Father{
        static  void m1() throws java.io.IOException {}
    }
    class Son extends Father{
        static void m1() throws java.lang.Exception {}
    }
    是不能编译的:出错提示“mi() in Son cannot override m1() in Father” - 但是这种对于static方法的override不能被“多态式后期绑定”(所以也就部份
       失去了override对于OO多态的意义)
    class Father{
        static void m1(){
            System.out.println("Father");
        }
    }
    class Son extends Father{
        static void m1(){
            System.out.println("Son");
        }
    }
    public class Test {
        public static void main(String[] args){
            Father.m1();
            Son.m1();        Son x = new Son();
            ((Father)x).m1();
            ((Son)x).m1();
        }
    }
    输出:
    Father
    Son
    Father
    Son
    这个结果说明:static方法可以被override,但不能被“多态式后期绑定”,所以也就
    部份失去了override对于OO多态的意义。因为override在OO中的一个重要作用就是支持
    多态。也可以这样认为:Java中的static方法在被override时不支持OO多态。