Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Overriding question  RSS feed

 
Alistair Burrowes
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The following code outputs:

subcov
5

Can someone tell me why? I understand the subcov but for the life of my I can't figure out why 5 and not 6 is returned by x.

class A {
int x = 5;
}

class B extends A{
int x = 6;
}

public class CovariantTest {
public A getObject() {
System.out.println("topcov");
return new A();
}

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

class SubCovariantTest extends CovariantTest {
public B getObject() {
System.out.println("subcov");
return new B();
}
}
[ December 02, 2005: Message edited by: Alistair Burrowes ]
 
Alistair Burrowes
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok I think I have this figured out.

Even though getObject from SubCovariantTest is being run, because it is being run by the container c1 which is CovariantTest, the return type is cast as the return type of getObeject in ConvariantTest.

Can someone confirm this is correct?
 
Naresh Gunda
Ranch Hand
Posts: 163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi
----------------------------------------------------------------------
class SubCovariantTest extends Fourtynine {
------------------------------------------------------

No defination for 'Fourtynine' class..

Regards
Naresh
 
Alistair Burrowes
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Oops I stuffed up the example.

class A {
int x = 5;
}

class B extends A{
int x = 6;
}

public class CovariantTest {
public A getObject() {
System.out.println("topcov");
return new A();
}

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

class SubCovariantTest extends CovariantTest {
public B getObject() {
System.out.println("subcov");
return new B();
}
}
 
Naresh Gunda
Ranch Hand
Posts: 163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When an instance method is invoked on an object using a reference, it is the class of the current object denoted by the reference, not the type of the reference.


When a field of an object is accessed using a reference, it is the type of the reference , not the class of the current object denoted by the reference.

Hope u got it now.

Regards
Naresh
 
Alistair Burrowes
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That doesn't make much sense to me. Would you be able to tie your answer into the question/code?
 
Purujit Saha
Ranch Hand
Posts: 86
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Alistair Burrowes
Please post some valid code.

I think your code should be,

class A
{
int x = 5;
}

class B extends A
{
int x = 6;
}

public class CovariantTest
{
public A getObject()
{
System.out.println("topcov");
return new A();
}

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

class SubCovariantTest extends CovariantTest
{
public A getObject() // as overridden method should have same return type
{
System.out.println("subcov");
return new B();
}
}

--------------------------
Now let me explain,


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

CovariantTest c1 = new SubCovariantTest(); this line will call the constructor of SubCovariantTest & create an object & referenced by super class instance.so, "subcov" will be printed.

Now , when you call c1.getObject(), the overridden method of SubCovariantTest will be called & return an object of class B wrapped into super class A.
so, when you call c1.getObject().x , it return instance variable of class A not B.

Now come to the point. You may ask why in case of methode calling a subclass object wrapped into a super class object is calling the overriden method & incase of variable calling its calling the super class variable.

The reason behind it is variables can't be overridden only it can be hidden.Only methods of the super class can be overridden in subclass.

I hope this will help you.

thnx
[ December 02, 2005: Message edited by: Purujit Saha ]
 
Alistair Burrowes
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Purujit Saha,

You are correct that in 1.4 an overriding method must have the same return type of its parent method. However in 1.5 the overriding method can return a subclass of the object returned in the parent method. Sorry perhaps I should have been clearer that this is 1.5.

Thus the code complies and runs fine, an object of type B is returned by getObject in SubCovariantTest yet A.x is printed out. I have now come to realise that even though getObject is called in SubCovariantTest, the B object returned is cast as A automattically as this is what the parent method returns. This is why A.x is called.
[ December 02, 2005: Message edited by: Alistair Burrowes ]
 
Steve Liem
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
System.out.println(c1.getObject().x);

getObject() returns a new B();
But B extends A.
So getObject will also call the constructor of class A.
So x = 5.

Remember: "B HAS-A x in A".
And x is an int. (primitive)
Not an object.

[ December 03, 2005: Message edited by: Steve Liem ]
[ December 03, 2005: Message edited by: Steve Liem ]
 
Alistair Burrowes
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think you are incorrect Steve,

If you replace

System.out.println(c1.getObject().x);

with

System.out.println(new B().x);

The output is 6 and not 5. Also the object coming back is definetly an A even though the getObject method from B is called. EG.

B newb = c1.getObject(); //compile error - cannot implicitly convert A to B.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!