Results 1 to 17 of 17
  1. #1
    vysh is offline Member
    Join Date
    Apr 2009
    Posts
    11
    Rep Power
    0

    Default Can anyone tell me how this output?

    Hi all,

    I am not sure how this output came.

    Java Code:
    class Foo
    {
    	public int a;
    	public Foo() 
    	{
    		a = 3;[B]//(2)[/B] 
    		System.out.println("foo");
    	}
    	public void addFive()
    	{
    		a += 5;
    	}
    } 
    public class Bar extends Foo
    {
    	public int a;
    	public Bar()
    	{ 
    		a = 8;
    		System.out.println("bar");[B]//(3)[/B]
    	}
    	public void addFive() 
    	{ 
    		this.a += 5; [B]//(4)[/B]
    	}
    	public static void main(String args[])
    	{
    		Foo foo = new Bar();
    		foo.addFive();[B]//(1)[/B]
    		System.out.println("Value: " + foo.a);
    	}	
    }
    I have numbered the steps through which the code will traverse according to my assumption. Can anyone tell where am i going wrong?

    The output which i am getting is :

    foo
    bar
    Value: 3

    The output which i think should be is '13'

  2. #2
    OrangeDog's Avatar
    OrangeDog is offline Senior Member
    Join Date
    Jan 2009
    Location
    Cambridge, UK
    Posts
    838
    Rep Power
    6

    Default

    Very good question.

    While methods are virtualised, fields are not. The methods you call depend on the type of the object, while fields you refer to depend on the type of the variable.

    Your object foo has two fields - Foo.a and Bar.a. Calling foo.addFive() increases Bar.a to 13 because foo is a Bar. Refering to foo.a gives you Foo.a (which is still 3) because foo is a Foo variable.
    Don't forget to mark threads as [SOLVED] and give reps to helpful posts.
    How To Ask Questions The Smart Way

  3. #3
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default

    I don't think the order indicated in your code is right.

    Java Code:
    class Foo
    {
        public int a;
        public Foo() 
        {
            System.out.println("a = 3;//(2) starting");
            a = 3;//(2) 
            System.out.println("  a = 3;//(2) done");
            System.out.println("foo");
        }
        public void addFive()
        {
            System.out.println("a += 5; starting");
            a += 5;
            System.out.println("  a += 5; done");
        }
    } 
    public class Bar extends Foo
    {
        public int a;
        public Bar()
        { 
            a = 8;
            System.out.println("System.out.println(\"bar\");//(3) starting");
            System.out.println("bar");//(3)
            System.out.println("  System.out.println(\"bar\");//(3) done");
        }
        public void addFive() 
        { 
            System.out.println("this.a += 5; //(4) starting");
            this.a += 5; //(4)
            System.out.println("  this.a += 5; //(4) done");
        }
        public static void main(String args[])
        {
            System.out.println("Foo foo = new Bar() starting");
            Foo foo = new Bar();
            System.out.println("  Foo foo = new Bar() done");
            System.out.println("foo.addFive();//(1) starting");
            foo.addFive();//(1)
            System.out.println("  foo.addFive();//(1) done");
            System.out.println("Value: " + foo.a);
        }	
    }

  4. #4
    OrangeDog's Avatar
    OrangeDog is offline Senior Member
    Join Date
    Jan 2009
    Location
    Cambridge, UK
    Posts
    838
    Rep Power
    6

    Default

    Run it though a debugger and the correct annotations are
    Java Code:
    class Foo
    {
    	public int a;
    	public Foo() 
    	{
    		a = 3; //(2) 
    		System.out.println("foo");
    	}
    	public void addFive()
    	{
    		a += 5;
    	}
    } 
    public class Bar extends Foo
    {
    	public int a;
    	public Bar()
    	{ 
    		a = 8; //(3)
    		System.out.println("bar");
    	}
    	public void addFive() 
    	{ 
    		this.a += 5; //(5)
    	}
    	public static void main(String args[])
    	{
    		Foo foo = new Bar(); //(1)
    		foo.addFive(); //(4)
    		System.out.println("Value: " + foo.a);
    	}	
    }
    Don't forget to mark threads as [SOLVED] and give reps to helpful posts.
    How To Ask Questions The Smart Way

  5. #5
    jim153 is offline Member
    Join Date
    Apr 2009
    Location
    China
    Posts
    8
    Rep Power
    0

    Default

    Please remeber foo is Foo reference.

  6. #6
    mgrootsch is offline Member
    Join Date
    Sep 2008
    Posts
    4
    Rep Power
    0

    Default

    Your Bar.a is not the overridden version of Foo.a although it may seem that way. They are independent.
    Try adding the method:

    public int getA() {
    return a;
    }

    to both Foo and Bar.

    And in your main(),
    replace "+ foo.a;" by "..+ foo.getA());."

    You'll see the difference.

  7. #7
    angryboy's Avatar
    angryboy is offline Senior Member
    Join Date
    Jan 2009
    Posts
    742
    Rep Power
    6

    Default

    Or you can use typecasting:
    Java Code:
    System.out.println("Value: " + ((Bar)foo).a);
    But generally, you should make field private.
    USE CODE TAGS--> [CODE]...[/CODE]
    Get NotePad++ (free)

  8. #8
    Steve11235's Avatar
    Steve11235 is offline Senior Member
    Join Date
    Dec 2008
    Posts
    1,046
    Rep Power
    7

    Default

    In think the previous posts explained the problem, but I'm going to take a shot at it, too...

    Subclasses can override methods, but not fields. What you did is called "hiding" the field. You have two fields with the same name, one in each class.

    Since your Bar class extends Foo, it has two fields named "a". When you specified class Foo, even though you were using a subclass, that caused the Foo version of a to be retrieved. You would have to cast the foo *field* to type Bar in order to retrieve the Bar version of a.

    Therefore:

    Don't hide fields. You can also cause this by specifying method parameters or fields that have the same name as your instance fields. I suggest putting a prefix, such as "i" or "_", on all instance fields, so you won't accidentally hide them. Also, the compiler can generate warnings. The Eclipse IDE provides prefix support, so getter and setter names won't include the prefix. The same applies to parameters.

    Declare all your instance fields private, and provide getters and setters for *any* class that accesses them. Don't give in to the temptation to use default or protected scope!

    In general, *always* do things the "right" way. Once you get in the habit, it doesn't take any more time, and you will save hours of needless debugging. This is coming from someone who is writing "Habits of the Constitutionally Lazy Programmer". Well, I would be, if I got around to it...

  9. #9
    vysh is offline Member
    Join Date
    Apr 2009
    Posts
    11
    Rep Power
    0

    Default

    Thanks everyone. So i understand that fields are not overridden. foo.a and bar.a are different. But what doubt i have now is i have called foo.a only after foo.addFive() which should have changed the value of a to 8. I wonder why even this has not happened.

    By the way, i had problems in logging in for the past few days. Did anyone had similar problems?

  10. #10
    RamyaSivakanth's Avatar
    RamyaSivakanth is offline Senior Member
    Join Date
    Apr 2009
    Location
    Chennai
    Posts
    812
    Rep Power
    6

    Default

    Hi,
    Here no pass by reference right? How can the a value will be 8?
    -Regards
    Ramya
    Ramya:cool:

  11. #11
    RamyaSivakanth's Avatar
    RamyaSivakanth is offline Senior Member
    Join Date
    Apr 2009
    Location
    Chennai
    Posts
    812
    Rep Power
    6

    Default

    Hi,
    Steve clearly mentioned regarding this.

    variable cannot be overriden.

    Foo foo = new Bar();
    1.For the below line if u put SOP then a value will be 13.When method is called ,Bar will be taken into consideration.
    foo.addFive();//(1)

    2.When the variable is called then Foo will be taken into consideration.Here we cant hide the original parent class variable with child class eventhough, you assign child class object ,so value of a is 3 for the below line.
    System.out.println("Value: " + foo.a);
    -Regarrds
    Ramya
    Last edited by RamyaSivakanth; 05-08-2009 at 01:35 PM.
    Ramya:cool:

  12. #12
    OrangeDog's Avatar
    OrangeDog is offline Senior Member
    Join Date
    Jan 2009
    Location
    Cambridge, UK
    Posts
    838
    Rep Power
    6

    Default

    foo.addFive() adds 5 to Bar.a
    Don't forget to mark threads as [SOLVED] and give reps to helpful posts.
    How To Ask Questions The Smart Way

  13. #13
    Steve11235's Avatar
    Steve11235 is offline Senior Member
    Join Date
    Dec 2008
    Posts
    1,046
    Rep Power
    7

    Default

    Actually, the method used is the Bar version, which acts on Bar.a

    The result is that Foo.a is 3, unchanged, while Bar.a is 13

  14. #14
    OrangeDog's Avatar
    OrangeDog is offline Senior Member
    Join Date
    Jan 2009
    Location
    Cambridge, UK
    Posts
    838
    Rep Power
    6

    Default

    Of course, foo.addFive() calls Bar.addFive(), not Foo.addFive().
    Hurrah for naming conventions.
    Don't forget to mark threads as [SOLVED] and give reps to helpful posts.
    How To Ask Questions The Smart Way

  15. #15
    angryboy's Avatar
    angryboy is offline Senior Member
    Join Date
    Jan 2009
    Posts
    742
    Rep Power
    6

    Default

    this should clear things up... or maybe confuse you even more...
    Java Code:
    public class FooOrBarTest {
      public static void main(String[] args){
        Foo foobar = new Bar();
        
        // NAME FIELD
        System.out.println(foobar.NAME); // FOO
        System.out.println(((Foo)foobar).NAME); // FOO
        System.out.println(((Bar)foobar).NAME); // BAR
        
        // TOSTRING() METHOD
        System.out.println(foobar); // BAR
        System.out.println(((Foo)foobar)); // BAR
        System.out.println(((Bar)foobar)); // BAR
      }
    }
    
    class Foo {
      final String NAME = "FOO";
      
      @Override
      public String toString(){
        return this.NAME;
      }
    }
    
    class Bar extends Foo {
      final String NAME = "BAR";
      
      @Override
      public String toString(){
        return this.NAME;
      }
    }
    USE CODE TAGS--> [CODE]...[/CODE]
    Get NotePad++ (free)

  16. #16
    vysh is offline Member
    Join Date
    Apr 2009
    Posts
    11
    Rep Power
    0

    Default

    Thanks everyone. I thought that 'foo.addFive()' will call addFive() method in Foo. But i understood that it actually calls the method in Bar. So foo.a still remains 3.

  17. #17
    Steve11235's Avatar
    Steve11235 is offline Senior Member
    Join Date
    Dec 2008
    Posts
    1,046
    Rep Power
    7

    Default

    Netbeans has a new coding assist feature. When you violate basic coding principles, such as hiding a field, it executes the following method:

    System.getDevices().getKeyboard().setHighVoltage() ;

    I understand that it is quite effective...

Similar Threads

  1. Java, output string, getting correct output? HELP!
    By computerboyo in forum New To Java
    Replies: 2
    Last Post: 02-25-2009, 11:44 PM
  2. what the outPut
    By alksam in forum Advanced Java
    Replies: 5
    Last Post: 12-25-2008, 01:44 PM
  3. What will be output and why
    By huma in forum Threads and Synchronization
    Replies: 4
    Last Post: 06-26-2008, 10:14 PM
  4. output
    By Camden in forum New To Java
    Replies: 3
    Last Post: 12-01-2007, 10:34 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •