• 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
  • Paul Clapham
  • Tim Cooke
  • Jeanne Boyarsky
  • Liutauras Vilda
Sheriffs:
  • Frank Carver
  • Henry Wong
  • Ron McLeod
Saloon Keepers:
  • Tim Moores
  • Frits Walraven
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
Bartenders:
  • Al Hobbs
  • Piet Souris
  • Himai Minh

Covariant type problem question

 
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey guys!

I was just taking a quiz session on WhizLabs and then when I came to this question, I was stumped. I thought it would print out 6, but it printed out 5 instead. Why?

If I understand correctly, c.getObject() calls on SubCovariantTest's getObject method which returns a B object. Where I'm confused is when you call c.getObject().x. Shouldn't it return the B objects x value?

----------------------------------------------------

class A {
int x = 5;
}

class B extends A {
int x = 6;
}

public class CovariantTest {

public A getObject() {
System.out.println("In A");
return new A();
}

public static void main(String[] args) {
CovariantTest c = new SubCovariantTest();
System.out.println(c.getObject().x);
}
}

class SubCovariantTest extends CovariantTest {
public B getObject() {
System.out.println("In B");
return new B();
}
}
 
Greenhorn
Posts: 20
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Not that it helps any, but when I traced through it, I also came up with 6.

I played around with the code, thinking maybe it had something to do with the accessibility of the "int x" values in the super and sub classes (A & B), but nothing panned out.
[ June 20, 2007: Message edited by: Brad Clarke ]
 
Ranch Hand
Posts: 377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

instance variables are handled like static methods. The selection is based on the type of the reference and not on the type of the object.
 
Brad Clarke
Greenhorn
Posts: 20
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This is just me more or less thinking out loud as i'm still not getting why 5 is printed and not 6.

Based on what the JLS says, the definition of x in class B "should" be hiding the definition of x in class A, but it doesn't appear to be in this scenario.

When the code executes, it runs the overridden version of getObject() that returns a B, says that it's in the B method, yet we end up with the x value from class A. Even if you define variable c as type SubCovariantTest it still prints out 5. EDIT - When c is type SubCovariantTest, it prints out 6. Not sure what I did last night, but it wasn't right
[ June 22, 2007: Message edited by: Brad Clarke ]
 
Ranch Hand
Posts: 38
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,
If you change the type of c to subCovariantTest it prints 6 not 5
 
Ranch Hand
Posts: 1274
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Howdy ranchers,

especially Howdy, David, as this seems to be your first posting on the ranch.

So welcome to the ranch!



You came up with one of the hardest nuts to crack - really!

David (you!) asked:

Shouldn't it return the B objects x value?


That's what you would expect in the first place. But there is a thing called synthetic bridge. It is used to assure that a covariant return is at all possible. And: no, it does not return an object of type B.


The following is not your original example, but - I am lazy and had this already filed...


Output will be:
Covariance Demo
Child
gimme an A!

The structure of the synthetic bridge is included as pseudocode above.
In order for ChildCovar to be able to return a subclass of A, it has to make a "virtual" method that returns an A and so follows the rule of returning the appropriate return type. And this returns an A type.
It must do so because the variable "mixed" is polymorphic, and of type A.
It can easily be rereferenced to an object of super type A and can therefore only accept, that the method getObject returns an A and not a B.

Proposal:

After your output line System.out.println(c.getObject().x);
try these extra lines:
A a = c.getObject();
B b = c.getObject();
and look what's happening.


That should clear your question about 5 or 6.



Note however that this synthetic-bridge-thing will only be used, if you have a polymorphic parentCovar / childCovar object as in these examples.
To prove this hang these lines:

System.out.println("\nother example:");
ChildCovar baby = new ChildCovar();
B b2 = baby.getObject();
System.out.println(b2.s);
System.out.println("b2 or not b2, this is here the question");

at the end of the main method of class Main in my example.


Next time an easier question, please



One hint still remains:
There is a code tag, when you post code you should hit the button labeled

Doing so ensures that your indentations (TAB letters and spaces) are properly displayed.

Yours,
Bu.
 
And then we all jump out and yell "surprise! we got you this tiny ad!"
the value of filler advertising in 2021
https://coderanch.com/t/730886/filler-advertising
reply
    Bookmark Topic Watch Topic
  • New Topic