class ClassA{
public void f1(){
}
public void f2(){
f1();
}
}
public class ClassB extends ClassA{
private int i = 0;
public void f2(){
super.f2();
}
public void f1(){
i++;
}
public int getI(){
return i;
}
public static void main(String args[]){
ClassB ob = new ClassB();
ob.f2();
System.out.println("Now, ClassB.i = "+ob.getI());
}
}
请问这时最后的输出是什么??为什么??

解决方案 »

  1.   

    那依各位看来,这个结果的出现算不算是JAVA设计的一个不足??
      

  2.   

    public class ClassB extends ClassA{
    private int i = 0;
    //覆盖ClassA中的f2()方法
    public void f2(){
       super.f2();//=========>f1();即调用f1()方法
    }

    //覆盖ClassA中的f1()方法
    public void f1(){
       i++;
    }
    public int getI(){
    return i;
    }
    public static void main(String args[]){
        ClassB ob = new ClassB(); //此时ClassA的f1()方法已经被ClassB中f1()方法覆盖
        ob.f2();
        System.out.println("Now, ClassB.i = "+ob.getI());
    }
    }因此输出应该是Now, ClassB.i = 1
    这个好像在模式中经常用到,只不过它把ClassA作为接口提供给用户调用,而具体的实现
    什么的都由它的子类来解决。这样如果我不给出ClassB的代码就算你拿到ClassA也没用,
    仍旧不能知道具体的实现细节。所以,有些软件公司会把它的一些接口公布出来,具体的
    实现可就。
    嘿嘿!!
      

  3.   

    很显然ClassB在调用f2()方法时无意改变自己的私有成员i,但事实上却不然,这样如果ClassB的设计者不知道ClassA中f2()方法的实现细节的话,岂不是很难查出出错(i的值改变这一事实)的原因来??
      

  4.   

    class ClassA{
    public void f1(){
    }
    public void f2(){
    f1();
    }
    }
    public class ClassB extends ClassA{
    public void f1(){
    super.f2();
    }
    public static void main(String args[]){
    ClassB ob = new ClassB();
    ob.f1();
    }
    }
    这个程序还会抛出StackOverflowError
      

  5.   

    在我看来,既然使用了super引用,就应该全部使用父类的方法,而不是一会儿用父类的,一会儿又用子类的。
      

  6.   

    我理解了你的意思,你想说的是父类的方法在被子类覆盖以后还能被调用是不是??
    直接用super.f1()不就ok了吗?
    你是不是以为在ClassB中的f2()调用super.f2()会调用到父类的f1()方法了??
    个人认为:1)这里在执行f2()的时候ClassB已经将父类的f1()覆盖了,
              2)你所new出来的是ClassB的对象实例(当然同时也是ClassA的实例),但是
                 他在找f1()时首先会看ClassB中是否也有f1()如果有,调用。如果
                 没有则认为你是使用从父类ClassA中继承来的f1();                        
              3)一个父类本身就应该是子类共同特征的抽象,在这里i仅是子类ClassB
                 的一个属性而以,就算程序运行后,ClassB出现问题也不会影响到ClassA
                 的其他子类。
    楼上认为java这样设计到底不好在哪呢??
    本人认为楼上的程序中看super.f2()乃多此一举,本来ClassB中的f2()方法就已经是继承了ClassA
    中的f2()方法,为何又要让他去super呢??
    以上仅个人意见,对事不对人。
      

  7.   

    例子二:递归调用自己没有结束的情况抛出StackOverflowError非常正常。
    这另一个方面表明java的异常处理非常不错啊!!
      

  8.   

    runtime binding, 这都算java不足?  晕出现栈溢出完全是你程序写的有问题
      

  9.   

    汗一个~~~~~
    楼主对JAVA知几何? 就能指出其不足?
      

  10.   

    这哪算java的不足阿..
    f2()里super了,那表示f2这个方法super了,
    你把f1()覆盖了,这和你是否super了f2并没有直接关系,造成这种结果的原因是你覆盖了f1()这个方法。你昨天穿了黑裤子,里面放了10块钱。
    今天你的女友把10元换成了1元放入黑裤子,你又穿黑裤子,你去买可口可乐,发现钱不够,于是你就骂了黑裤子:"你的设计真不合理,10元明明是我放的,你咋让人把它换成1元了,谁弄得你也不说,你好讨厌哦"
      

  11.   

    hykwolf(Yankang Hu) 编的笑话不错哦
      

  12.   

    不过仔细想一想,也经常这样用呀,难道有别的写法么
    比如 public void f(){
    super.f(); // 父类过程
                      ..... // 子类过程 }
      

  13.   

    回:[genify(cjf)]我理解了你的意思,你想说的是父类的方法在被子类覆盖以后还能被调用是不是??
    ////////////////////////////////////////////////////////////////
    不是说ClassB继承了ClassA的f2()方法,而是覆盖.但有时你却不得不先调用父类的方法以完成一些功能,但如果ClassB的设计者不知道ClassA中f2()的实现细节,就会出现意想不到的问题,不是吗?
      

  14.   

    那个StackOverflowError也是因为ClassB的设计者不知道ClassA中f2()的实现细节所造成的,不是吗?
    其实我在写这个例子时我也知道我在写什么,只是因为觉得奇怪才拿出来让大家看看的.
    我在ClassB的f2()中查看了super.getClass(),结果是"class ClassB",在ClassA中的f2()也一样:当我调用super.f2()时,在ClassA的f2()中输出的this.getClass()也是"class ClassB".
    我所奇怪的是,既然我明确地说明我调用的是父类的方法(super.f2()),我个人觉得JAVA应该了解这一点而在ClassA的f2()中全部调用本身的方法和属性.
    <<<只是做一些讨论,请不要伤了和气...>>>
      

  15.   

    jihanzhong(逍遥),这么喜欢分数我就多给你几分吧,我是无所谓的...
      

  16.   

    既然你去super它,你就应该知道它的作用是什么吧
      

  17.   

    不是JAVA设计的不合理, 而是楼主设计的不合理.楼主在父类中已经定义了f1()方法, 而在子类中又重新定义了它, 你这样就是告诉JAVA, f1()是一个动态绑定方法, 所以不管它在哪里被调用, 它都遵循JAVA的动态绑定规则来调用.如果你认为, 父类的f1()不应该被子类重定义(覆盖), 那么它完全没有必要设计成public, 而应该是final的或者干脆是private的. 就像楼上有位朋友说的那样, 你明明知道裤子的口袋是敞开的, 就不应该相信里面的钱不会被别人动过. 这是一个很基本的常识.
      

  18.   

    多态性导致,不是bug这样的设计就必须对这种结构有所估计,楼上说的很明白了
      

  19.   

    hykwolf(Yankang Hu)的比喻要狂赞一个!!
    鼓励!!!!!哈哈!!!