你把我搞胡涂了,你是想说应该调用Super::methodA而不应该调用SubClass::methodA是吗?原因是Java 中一切方法缺省都等同于C++中的virtual函数,这种调用方法正是C++中virtual的原意呀,就是可以不用管实际类型是什么,只要用基类指针去引用方法,就会自动调用适当的子类中的相同方法。

解决方案 »

  1.   

    继承的原则是如果子类中重写父类方法,父类方法就会被屏蔽掉!除非显示调用 如 super.method(),你在子类中重写了methodA(),虽然,你显示调用父类的methodB()但没有 显示调用父类的methodA(), 子类的methodA()还会屏蔽掉父类的methodA().在执行super.metnodB()应执行的时子类的methodA().这只是我的想法,如有不对请指出!!~
      

  2.   

    邪门,按我的理解应该是:
    Super::methodASuper::methodB call Super::methodASuper::methodASuper::methodB call Super::methodASubClass::methodB call Super::methodA请高手指点!
      

  3.   

    我认为这是java的一个bug,虚拟机在实现动态绑定的时候,没考虑到这点。
      

  4.   

    啊?这是OO的精髓所在呀?
    去好好看看MFC中对virtual的使用吧!
      

  5.   

    因为在java中不需要声明,但所有的方法缺省都是virtual的!
      

  6.   

    不相信的话,在C++中把super的methodB方法前面加个virtual去试试吧。
      

  7.   

    gcli123456(国臣) ,说的很对!~
      

  8.   

    to:luodi你如果相信我的话,你自己试试,在c++即使是虚拟函数,也是调用的super::methodA而不是SubClass::methodA。我自己刚做了这个试验。
    我想这是java的一个bug,大家看呢?
      

  9.   

    gcli123456说的只在Java中很对!
    不相信去C++中试一下。在C++中不用virtual来声明super::methodA()的话,needle说的才对!
      

  10.   

    呵呵,我说的就是在java环境中,C++不是彻底的面向对象编程!
      

  11.   

    to:luodi
    I am sorry!你说的对,给你加18分(我在c++中调试时,打错一个字符!)
    下面还有问题呢,这么办呢
    那有什么方法可以调用Super::methodA而不是调用SubClass::methodA
      

  12.   

    needle() 很不公平阿,你可是java 环境!!!!! C++不是彻底的面向对象编程! 
      

  13.   

    你在子类中不重写methodA()不就行了!!!
      

  14.   

    to:luodi
    你说的对,我在C++调试是把Super::methodB()打成Super::methodA啦(真该死),java中实现的方法确实象C++中的虚拟函数,因为所有的方法都是动态绑定的吗!下面这个问题,在java中这么实现:
    我想在调用SubClass的methodB时,象C++一样,得到这个结果:
    Super::methodA
    Super::methodB call Super::methodA
    SubClass::methodB call Super::methodA
    该这么办
      

  15.   

    to:luodi
    先给你加18分,你说出了是什么原因,但是还没答出如何解决呢,^_^
      

  16.   

    class Super {
        public void methodA() {
            System.out.println("Super::methodA");
        }
        
        public void methodB() {
            methodA();  //大家注意这里
            System.out.println("Super::methodB call Super::methodA");        
        }
    }class SubClass extends Super {
        public void methodA() {
         super.methodA();
            System.out.println("SubClass::methodA");
        }
        
        public void methodB() {
            super.methodB();
            System.out.println("SubClass::methodB call Super::methodA");        
        }
    }
    public class Test
    {
        public static void main(String[] args) {
            Super a = new Super();
            SubClass b = new SubClass();
            
            a.methodB();
            b.methodB();
      }
    }输出结果是:
    Super::methodA
    Super::methodB call Super::methodA
    Super::methodA
    SubClass::methodA
    Super::methodB call Super::methodA
    SubClass::methodB call Super::methodA
      

  17.   

    为啥我总是丢贴子,tnnd!!
    to:luodi问题找出原因啦,先给你加18分
    上面的这半个问题,有办法吗!
      

  18.   

    gcli123456, hehehe ... :)
      

  19.   

    to :wxyxl
    你不能更改我的SubClass的methodA(),那就达不到我的原意啦
      

  20.   

    大家对我不满啦,gcli123456也答的不错,也给加18分,我再把这个问题再提一次,希望有人能解决下半个问题
      

  21.   

    同意wxyxl的看法,我个人看法:如果你在java中用同样的参数来声明子类与父类中相同的方法的话,是无论如何也无法完成你的要求的。有没有高手有不同意见?
    所以一个合理的做法确实是:不是动态绑定,而直接用重载就是了,也就是用wxyxl说的从参数上区别,因为,overload与virtual是完全不同的。
      

  22.   

    to:wxyxl
    那我的程序,还能看吗!我把下半个问题,又提了一下,欢迎大家讨论!
      

  23.   

    to needle():
    什么叫“还能看吗!”?
      

  24.   

    既然Java语言就是这样,那有什么办法!
    其实什么东西只要能实现就可以!难道你要
    SUN把它重写一下!可能重写以后,你已经不用
    了,有什么意义呢!既然他本身不支持,难道
    我不可以想别的办法!”条条大路通北京“没听说过吗?
      

  25.   

    怎么连这个都没搞懂?!这就是所谓多态(多形)性,OO的精髓啊,JAVA默认就是虚函数。
      

  26.   

    大家看看这个可以达到要求:
    class Super {
        public static void  methodA() {
            System.out.println("Super::methodA");
        }
        
        public void methodB() {
            methodA();  //大家注意这里
            System.out.println("Super::methodB call Super::methodA");        
        }
    }class SubClass extends Super {
        public static void methodA() {    
            System.out.println("SubClass::methodA");
        }
        
        public void methodB() {
            super.methodB();
            System.out.println("SubClass::methodB call Super::methodA");        
        }
    }
    public class Test
    {
        public static void main(String[] args) {
            Super a = new Super();
            SubClass b = new SubClass();
            
            a.methodB();
            b.methodB();
      }
    }
    输出结果是:
    Super::methodA
    Super::methodB call Super::methodA
    Super::methodA
    Super::methodB call Super::methodA
    SubClass::methodB call Super::methodA
    但是我不知道为什么把方法设置为静态的,他就去调用父类的方法:
    大家讨论一下!
      

  27.   

    难道静态的时候她就不上塑造型了吗?大家讲讲Static的内在意义吧!
      

  28.   

    静态的方法不但不上塑造型,而且也不用运行时绑定,按C++的实现方法,它根本就不在虚函数表中出现。在它的参数表中根本就没有一个隐含的this存在,所有编译时就决定了它会使用的方法。
    因为一个方法如果用static来声明,它实际上与一个全局函数没什么差别,你把它放在一个类中纯粹是为了使用类的命名空间。
      

  29.   

    Super::methodA
    Super::methodB call Super::methodA
    Super::methodA
    Super::methodB call Super::methodA
    SubClass::methodB call Super::methodA
      

  30.   

       class a1
                {
                 private void ma1() //注意不是public
                          {
                           list1.addItem ("a1------ma1");
                          }
                 public void ma2()
                         {
                         ma1();
                         list1.addItem ("a1-------ma2");
                         }
                }       class a2 extends a1
           {
               public void ma1()
                  {
                  list1.addItem ("a2-------ma1");
                  }
               public void ma2()
                 {
                  super.ma2();
                  list1.addItem ("a2-------ma2");
                 }
           }      //a1 tmp1=new a1();
          a2 tmp2=new a2();
          //tmp1.ma1();
          //tmp1.ma2();
          //tmp2.ma1();
          tmp2.ma2();sun的java没问题,她OOP很好,各中原因自己去想!
    注意private 而不是public
      

  31.   

    luodi(无知者无畏)说的对,改讨论问题关键就在这里
    所以要让虚拟机按照意图执行,要用static,在编译时就绑定,这就是所谓的前期绑定,编译原理讲得很清楚
    ^v^
      

  32.   

    class Super {
        public void methodA() {
            System.out.println("Super::methodA");
        }    public void methodB() {
            methodA();  //大家注意这里
            System.out.println("Super::methodB call Super::methodA");
        }
    }class SubClass extends Super {
        public void methodA() {
            System.out.println("SubClass::methodA");
        }    public void methodB() {//既然是Override,为什么还留有Super.methodB()的痕迹?
                               //我认为这里不会再象Super的methodB()一样去调用自己的
                               //methodA().
            super.methodB();
            System.out.println("SubClass::methodB call Super::methodA");
        }
    }
    public class Test
    {
        public static void main(String[] args) {
            Super a = new Super();
            SubClass b = new SubClass();        a.methodB();
            b.methodB();
      }
    }
      

  33.   

    终于明白,赞成的gcli123456(国臣)的观点.一但父类的方法被子类override后,在其子类中调用时就被子类的方法所替代所以有:class Super {
        public void methodA() {
            System.out.println("Super::methodA");
        }    public void methodB() {
            methodA();  //Step 2. Here, methodA() is overide by SubClass.
                        //So, call SubClass's methodA().
            System.out.println("Super::methodB call Super::methodA");
        }
    }class SubClass extends Super {
        public void methodA() {////Step 3
            System.out.println("SubClass::methodA");
        }    public void methodB() 
            super.methodB(); //Step 1
            System.out.println("SubClass::methodB call Super::methodA");
        }
    }
    public class Test
    {
        public static void main(String[] args) {
            Super a = new Super();
            SubClass b = new SubClass();        a.methodB();
            b.methodB();
      }
      

  34.   

    在Super类的methodB()方法调用methodA()时,改成this.methodA(),大家看看会有什么结果!!!
      

  35.   

    There are two things:
    1) public(and friendly) methods in java default to polymorphic (virtual in c++)
    2) If no explicit method call, all those method will be called dynamically (that is Late binding)In you code:
    1)You explicitly call super.methodB(), so compiler knew the binding information and compiler will make early binding for this call.
    2)However, in methodB()of Super class, you call methodA() which should be bound at run time in terms of offset in dynamic address table(say VTable in c++).
    So, at run time, when you call methodB on Derived class, it will call overriden methodA() of Derived class dynamically.