• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Junilu Lacar
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • Jeanne Boyarsky
  • Rob Spoor
  • Bear Bibeault
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Piet Souris
  • Carey Brown
  • Stephan van Hulst
Bartenders:
  • Frits Walraven
  • fred rosenberger
  • salvin francis

Overriding Instance Variables (help)

 
Greenhorn
Posts: 20
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 ]
 
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I meant overriding. oopsie
 
Nomi Malo
Greenhorn
Posts: 20
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Ranch Hand
Posts: 229
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 20
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Author
Posts: 84
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 ]
 
Tony Smith
Ranch Hand
Posts: 229
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
"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
Posts: 20
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
You showed up just in time for the waffles! And this tiny ad:
Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
reply
    Bookmark Topic Watch Topic
  • New Topic