This week's book giveaway is in the Servlets forum.
We're giving away four copies of Murach's Java Servlets and JSP and have Joel Murach on-line!
See this thread for details.
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Overriding Instance Variables (help) Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Overriding Instance Variables (help)" Watch "Overriding Instance Variables (help)" New topic
Author

Overriding Instance Variables (help)

Nomi Malo
Greenhorn

Joined: Mar 20, 2007
Posts: 20
Hi, Please have a look at this code:

SCANARIO 1:

public class A {
public int num=500;
public int getNum() {return num;}

public static void main(String args[]) {
A myA= new A();
System.out.println(myA.getNum());

B myB= new B();
System.out.println(myB.getNum());

A myC= new B();
myC.num=7777;
System.out.println(myC.getNum());
}
}

class B extends A {
public int num=8800;
private void print() {
System.out.println("sub class print message");
}
}

OUTPUT:
500
500
7777
first output is fine. What about instance of B class??? Rather then printing 8800, inherited value of 500 is printed. Is it because getNum() is only defined in supper class A?? But class B would also inherit getNum()... so should it not print 8800 on second line using the inherited getNum(). 3rd output again print inherited value of 7777 rather then 8800.

SCNARIO 2:
Copy getNum() method from superclass and paste it in class B. Now
OUTPUT:
500
8800
8800

Now since we have getNum in class B. It prints 8800 and ignore inherited values of num. I am confused because class B inherited getNum anyway so why do we need to write it explicitly in class B??

Please HELP!!!
[ September 11, 2007: Message edited by: Nomi Malik ]
Prasanna Rajaperumal
Greenhorn

Joined: Aug 28, 2007
Posts: 9
Hi Variable overloading is what likely you are expecting and Java doesnt do that. only methods can be overloaded.

Hope that explains all your questions
Prasanna Rajaperumal
Greenhorn

Joined: Aug 28, 2007
Posts: 9
I meant overriding. oopsie
Nomi Malo
Greenhorn

Joined: Mar 20, 2007
Posts: 20
But the output suggests that if you have an overriding method i.e getNum(), then class B num variables does override the inherited num value? Am I right? Kindly comment.

Thanks
Tony Smith
Ranch Hand

Joined: Jul 07, 2007
Posts: 229
I run your first senario through debugger and found out what happened.

B myB= new B();
System.out.println(myB.getNum());

creates a new B object and it certainly has the value 8800 to go along with it. However when you do myB.getNum(); the compiler is going to look for getNum() method. Even though you may get the idea that when you use extends you get all public members of the parent class copied into the child class. But that is not exactly how it works. I believe a parent object is created and then child object wraps around it. Meaning when you do myB.getNum(); it will check to see if there is an getNum() in the child class. If not, compiler will invoke getNum() in the parent class. Therefore the int num=500 in the parent class is invoked.

If you override the public int getNum() {return num;} in the child class by simply copying and pasting that line into class B some where. You should be able to get the 8800.

In the last output when you have myC.num=7777; again you are changing the value of 500 into 7777. The 8800 remains untouched. myC.getNum(); does exactly the same thing as myB.getNum(); Since no getNum(); is found in B so the one in A is invoked. And you got 7777.

Maybe someone else can explain this better. You just have to test it out yourself.
Nomi Malo
Greenhorn

Joined: Mar 20, 2007
Posts: 20
Thanks tony, I really appreciate that. Debugger does show that it jumps to class A getNum() method. But talking about B myB=new B(), note that debugger shows 500 as inherited value,then how come compiler does not have a way to know that getNum() is also inherited from the parent class.

You are right. We would need a better explanation from some expert.

Thanks again.
Peter Mularien
Author
Ranch Hand

Joined: Sep 06, 2007
Posts: 84
I believe this is called shadowing of instance variables, and is covered in the JLS here: 6.3.1.

A similar type of shadowing is called field hiding, which can occur when you have fields of the same name and mixed data types: 8.3.3.2.

(At least I think this is the difference between the two )
[ September 11, 2007: Message edited by: Peter Mularien ]

Author, Spring Security 3 (the Book), Packt Publishing, 2010
SCJP, OCP
Tony Smith
Ranch Hand

Joined: Jul 07, 2007
Posts: 229
"then how come compiler does not have a way to know that getNum() is also inherited from the parent class."

It's not that the compiler does not know, but it's how the java designer designed polymorphism this way. It's just the rule. It's like asking why i=i++; doesn't change the value of i. It's just the way they designed it.

One reason I can think of why it's designed this way is because if you have a long inheritance tree, if every code is copied exactly from parent object to child object to grand child object then the size would get very big and it will not be efficient. Actually I think I read that some where before.... So in terms of polymorphism, the deepest overridden method will be invoked. In your case, the deepest one is the one in the parent class, so that one gets called.
Nomi Malo
Greenhorn

Joined: Mar 20, 2007
Posts: 20
Thanks Tony and Peter. Take this example from link given by Peter:

Example: Hiding of Instance Variables

class Point {
int x = 2;
}
class Test extends Point {
double x = 4.7;
void printBoth() {
System.out.println(x + " " + super.x);
}
public static void main(String[] args) {
Test sample = new Test();
sample.printBoth();
System.out.println(sample.x + " " +
((Point)sample).x);
}
}

produces the output:

4.7 2
4.7 2

because the declaration of x in class Test hides the definition of x in class Point, so class Test does not inherit the field x from its superclass Point. It must be noted, however, that while the field x of class Point is not inherited by class Test, it is nevertheless implemented by instances of class Test. In other words, every instance of class Test contains two fields, one of type int and one of type double. Both fields bear the name x, but within the declaration of class Test, the simple name x always refers to the field declared within class Test. Code in instance methods of class Test may refer to the instance variable x of class Point as super.x.

Please read the lines in bold. So subclass does not actully inherit instance variables from superclass but subclass instances implement it. This is something new for me.

Thanks
 
wood burning stoves
 
subject: Overriding Instance Variables (help)
 
Similar Threads
why use getter setters in beans
Inner Classes
I used to think private variables are not inherited!!
anonymous class example
Insights into synchronization