10. public class Foo {
11. public int a;
12. public Foo() { a = 3; }
13. public void addFive() { a += 5; }
14. }
and:
20. public class Bar extends Foo {
21. public int a;
22. public Bar() { a = 8; }
23. public void addFive() { this.a +=5; }
24. }
invoked with:
30. Foo foo = new Bar();
31. foo.addFive();
32. System.out.println(”Value: “+ foo.a);
What is the result?
A. Value: 3
B. Value: 8
C. Value: 13
D. Compilation fails.
E. The code runs with no output.
F. An exception is thrown at runtime.
Answer: A答案是A,为什么不是13呢????

解决方案 »

  1.   

    1. public class Blip {
    2. protected int blipvert(int x) { return 0; }
    3. }
    4. class Vert extends Blip {
    5. // insert code here
    6. }
    Which five methods, inserted independently at line 5, will compile?
    (Choose five.)
    A. public int blipvert(int x) { return 0; }
    B. private int blipvert(int x) { return 0; }
    C. private int blipvert(long x) { return 0; }
    D. protected long blipvert(int x) { return 0; }
    E. protected int blipvert(long x) { return 0; }
    F. protected long blipvert(long x) { return 0; }
    G. protected long blipvert(int x, int y) { return 0; }
    Answer: ACEFG顺便讲一下这道题
      

  2.   

    对于属性,是不存在多态的。而是根据类名进行早绑定。
    32. System.out.println(”Value: “+ foo.a);打印的就是父类Foo的属性a。
      

  3.   


    但是30行构造出来的foo是子类Bar()的啊,他的属性应该a = 8????
      

  4.   


    foo是Foo类型引用,它会取Foo类的a
      

  5.   

    http://topic.csdn.net/u/20081127/18/dc4fd9f5-b197-44b8-b999-e142a5388389.html
    这个问题和这个大概差不多,类的属性是不存在多态性的。
    foo.a是父类对象的属性,foo.addFive()多态调用子类的方法因为foo引用的是一个子类实例构造对象,子类方法addFive()覆盖父类的addFive()方法。
    我想打给就是这么的吧,不知道正确否。
      

  6.   

    D. protected long blipvert(int x) { return 0; }
    我不明白这个。有没有人可以给予解释下下啦。。
    在我看来本应该是可以的呢。最起码也最简单地理解得到这样看起来确实是比基类的大了呀?不明白。
      

  7.   

    方法重写:子类继承父类,并在子类中定义一个与父类中的方法名称和参数都相同的方法(返回类型可以不同),就会覆盖父类中的方法,这就是方法重写,并且“重写”只有在类继承的时候才会发生上面是我从网上看到的一段话。。   
    D选项错误~·是指返回类型long和int不同,所以报错吗???
       如果把参数类型换一下的话~~比如E,F选项编译器就不会认为是重写父类的方法吗??
      

  8.   


    哪个类型引用它的属性就是哪个类型的吗??
    比如B继承A的话,A b = new B();这里实例b的属性是A的,方法是B的,这样说对吗???
      

  9.   


    F返回也是long,但是它的参数变了,这样编译器是不是就不认为是方法的重写了???
      

  10.   

    Foo foo = new Bar();
    等号左边你是把foo 声明为Foo类型,如果右边是定义一个Foo类的实例的话,那么你那么是把这个实例的引用赋给了foo,所以foo引用变量引用的foo.a将会是Foo实例中的变量a ,即a=3,而方法addFive()也是Foo中定义的方法,
    如果等号右边是定义一个Boo类的实例的话,那么你是把这个BOO实例的引用给了foo,这个时候foo引用变量引用的方法将会是Boo中的addFive()(addFive()中的a,也是Boo中的定义的a,用这方法得到a 的结果也是13,)但是foo引用的变量a就仍是Foo中定义的变量a,foo.a就是FOO中的a=3;
    一名句话,经多态中,变量是不可以实替换的,方法才可以,
      

  11.   


    若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法D. 如果是long则在编译时,会提示重写了父类的方法,但是返回类型不匹配
      

  12.   


     class Foo {
      public int a;
      public Foo() 
      { a = 3; }
      public void addFive() 
      { a += 5; } }
     
       class Bar extends Foo {
       public int a;
       public Bar() 
       { a = 8; }
       public void addFive()
       { this.a +=5; }  }
     public class Test2{
       public static void main(String[] args){
        //Foo foo = new Bar();
        Foo foo =new Foo();
        Bar bar=new Bar();
        System.out.println("Value: "+foo.a); //3
        System.out.println("Value: "+bar.a); //8
        foo=bar;
        System.out.println("Value: "+foo.a); //3
        System.out.println("Value: "+bar.a); //8
        foo.addFive();
        System.out.println("Value: "+foo.a); //3
        System.out.println("Value: "+bar.a); //13
      }
    }
    结果:c:\J>java Test2
    Value: 3
    Value: 8
    Value: 3
    Value: 8
    Value: 3
    Value: 13楼主明白了吧?父类属性是不被改变的,多态的重写只对方法而言。
      

  13.   

    属性只会被掩盖,你暂时看不到而已,你调用的
    System.out.println("Value: "+foo.a);之所以会输出3是因为你创建
    子类对象的时候会调用你的父类的默认的构造函数,把父类的属性a赋值为3(你的a的属性是public),
    当你调用父类foo.a时输出是3。
      

  14.   

    她只会看到该类(FOO)的属性和方法,只有当调用的方法被实际引用的对象的类重写的时候才会调用子类的方法。ok
      

  15.   


    class Foo {
      public int a;
      public Foo(){ 
       a = 3; 
      }
      public int addFive(){ 
       return a += 5;
      } }
     
       class Bar extends Foo {
       public int a;
       public Bar(){
         a = 8; 
       }
       public int addFive(){ 
        return this.a +=5; 
       }  }
     public class ClassVar{
       public static void main(String[] args){
          
      Foo foo=new Bar();
      System.out.println(foo.a);
      //foo.addFive();
      System.out.println(foo.addFive());
     
      }
    }这样就是13了,因为参数是值传递,并不改变传入的值
      

  16.   

    第一题:只有方法能重写    因为JVM在调用方法的时候会去找方法表,他能够找到子类重写后的方法并调用它。
    而实例变量却不会有这样的机制,他只能够找到父类中定义的变量
      

  17.   


    我想问一下Foo foo=new Bar()这样创建出来的实例foo它的属性a是3还是8呢???
      

  18.   

    第二题:
    重写的原则:
    首先,继承是重写的前提!
    1.方法签名必须相同(包括:方法名,参数个数,参数类型,参数顺序)
    2.方法的返回相同(可以不同,但要支持多态就要相同)
    3.访问权限不能比父类小(大于等于)
    4.抛出异常不能比父类大1. public class Blip {
    2. protected int blipvert(int x) { return 0; }
    3. }
    4. class Vert extends Blip {
    5. // insert code here
    6. }
    Which five methods, inserted independently at line 5, will compile?
    (Choose five.)
    A. public int blipvert(int x) { return 0; }  //这个是重写   public 的权限大于protected。没有任何问题    对
    B. private int blipvert(int x) { return 0; }  //权限变小  错
    C. private int blipvert(long x) { return 0; } //参数类型不一样,是子类的一个新方法  对
    D. protected long blipvert(int x) { return 0; } // 返回类型不一样 错
    E. protected int blipvert(long x) { return 0; }//参数类型不一样,是子类的一个新方法  对
    F. protected long blipvert(long x) { return 0; }//参数和返回类型不一样,是子类的一个新方法  对
    G. protected long blipvert(int x, int y) { return 0; //参数不一样  对
      

  19.   


    跟你拆开说:
    Foo foo; //在栈中创建一个Foo变量
    new Bar();//在堆中创建一个Bar类型对象,当然创建子类对象时先要创建父类的对象。所以在堆内存中是有两个对象的:一个是Bar的,一个是Foo的。 Bar中有一个a=8;Foo中有一个 a=3; 在编译时编译器只知道foo是Foo对像,他不知道他实际上指向了Bar对象。在编写的时候也只能.出Foo类中定义的成员。但在运行时,让foo指向了Bar的对象。这样就实现了类多态(父类变量指向子类对象)。这样在执行下面的方法时,他会先找方法表看子类对象对方法进行重写没有,如果有就调用子类重写后的方法。 而属性是没有这样的机制的,所以对于他来说他只知道堆内存中Foo的对象a,而不是去寻找Bar中对象的a
      

  20.   

    public class A{
      public int a=1;
    }public class B
      extends A{
      public int a = 2;
      public int b = 3;
    }A obj = new B();
    System.out.println(obj.a); //输出1//System.out.println(obj.b);//ERROR!因为在编译时,编译器并不知道a在运行时指向B的对象,所以这样会编译出错。其实如果是在运行时,这句话一点问题都没有Sytem.out.println(((B)obj).a);//输出2  其实obj本来就是指向B对象的,所以他实质上是个B类型。   把obj强制转换成真正属于自己的B类型时,他就可以访问到B里定义的a了
      

  21.   

    你把
    32. System.out.println(”Value: “+ foo.a);改成32. System.out.println(”Value: “+ (Bar)foo.a); 这样就能输出你要的13了
      

  22.   


    addFive()方法已经被子类重写了,所以foo.addFive()执行的是已经重写后的方法,此时执行addFive()方法的是Bar中的a,然而最后显示出来的是Foo中的属性a,我这样理解对不??
      

  23.   

    不同意你的看法,父类的属性也可以改变,只是看在什么情况下,当子类没有重写父类的addFive()时候,父类的a变成了8! class Foo {
     public int a;
     public Foo() { a = 3; }
     public void addFive() { a += 5; }
    }

     class Bar extends Foo {
     public int a;
     public Bar() { a = 8; }
    // public void addFive() { this.a +=5; } //不重写addFive()方法
    }
    public class Test1 {
    public static void main(String[]args){
    Foo f=new Bar();
    f.addFive();
    System.out.println(f.a);//输出8

    }
    父类中的所有属性都被子类继承下来,所有说Bar中有两个a,一个是父类的,一个是子类的,当Foo f=new Bar()时候,先调用父类的构造方法,所以Bar中的一个a(继承父类的a)变成了3,再调用子类自己的构造方法子类中的自己定义的a变成了8;这个时候调用f.addFive()时,由于子类的addFive()对父类的该方法进行了重写,所以就调用子类中的addFive()方法,此时Bar中自己定义的a为13.当没有重写的时候,改变的就是父类的a,父类的属性也就改变了!
    对这两句话的理解是Foo f=new Bar();f.a;
    当你向上转型的时候,Foo类型的Bar对象f只能看见Foo类型中的东西,并不能访问Bar中自己定义的成员变量,所以f.a调用的是基类的对象a,也就是子类从父类继承下来的a,不是自己定义的a!
             
      

  24.   


    没错就是这样CSDN上的朋友都是助人为乐的!即便你没分,论坛上的朋友也会帮助你的!    在帮助别人中巩固和提升自己的知识楼主看来是在准备SCJP考试啊。我也要考的
      

  25.   

    第一题:
     Foo f=new Bar();
     f.addFive();//此时调用的子类的方法
     System.out.println(f.a);//此时是调用父类的属性,父类的属性并没有改变,所以输出为3 Thingking in Java中有一段话可以很好的解释:
     对于属性和静态方法来说,调用取决于声明的类型,而对于其他的取决于运行时的类型,这里Foo是声明类型,Bar则是运行时的类型。第二题:
    应该是一个方法重写的问题:对于方法重写有一些限制:
     如果编译器认为是方法的重写的话,就会做一些限制,必须有相同的方法名,参数列表,和返回值,而其访问的可见度不能减小。