We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpSyntax Questions › Properties changing when casting Object
Page Index Toggle Pages: 1
Properties changing when casting Object (Read 933 times)
Properties changing when casting Object
Feb 24th, 2007, 12:00am
 
Hello. I am quite new to Java and very confused why, in the simple example below, the value of a property changes when casting an object to its superclass (note the last line of the listing):

Code:

class Super
{
public final String foo = new String("Super");
}

class Sub extends Super
{
public final String foo = new String("Sub");
}

Sub sub = new Sub();
Super subCast = (Super)sub;

println(sub.foo);
println(subCast.foo); // I don't understand why this gets the value "Super" now


This, on the other hand, does what I would expect:

Code:

class Super
{
public String foo = new String("Super");
}

class Sub extends Super
{
Sub()
{
this.foo = "Sub";
}
}

Sub sub = new Sub();
Super subCast = (Super)sub;

println(sub.foo);
println(subCast.foo); // Alright, the value stays "Sub" now.


Can anyone elaborate why this happens? Since I would like to declare the properties as public final, the example below seems a bit dirty to me.
Re: Properties changing when casting Object
Reply #1 - Feb 24th, 2007, 12:41am
 
I think it's because, final means final... unchangable.

When you cast it to super, the program looks at the Super's value.. and so prints the super's value, since the Sub's one can't change it, because it's final.

Once you're using it as the Super type, then it shouldn't go looking at the Sub value, since it's been told to treat it as the Super.

The second one works because it's not final, and so the sub can change the value, and there's only a single inctance of it.
Re: Properties changing when casting Object
Reply #2 - Feb 24th, 2007, 1:44am
 
No, actually that was my guess too, but this non-final example has exactly the same (bad) result:

Code:

class Super
{
public String foo = new String("Super");
}

class Sub extends Super
{
public String foo = new String("Sub");
}

Sub sub = new Sub();
Super subCast = (Super)sub;

println(sub.foo);
println(subCast.foo); // I don't understand why this gets the value "Super" now


Re: Properties changing when casting Object
Reply #3 - Feb 24th, 2007, 2:05am
 
You get the Super value, because you've told the program it's a Super, not a Sub., so a run time, it goes to see what type it is, sees it as a Super, and so prints the Super's version of the value.

What you're doing is creating a different variable in Sub, that just happens to have the same name.

I think if you added a method to sub like:
Code:
println(foo);
println(super.foo);

You'd get both printed, since they're different variables.
Re: Properties changing when casting Object
Reply #4 - Feb 24th, 2007, 2:14am
 
By casting I'm not creating a new variable (or instance), only a reference to the original object, but of class Super. The thing I'm confused about is: Why does Java use the value declared in the superclass after casting, but ONLY if I redeclare the property in the subclass?
Re: Properties changing when casting Object
Reply #5 - Feb 24th, 2007, 2:25am
 
When you create an object of type Sub, it also creates an object of type Super, since Sub extends Super.

So you do new Sub(), what java does is looks at what Sub is, sees it extends Super, so before it does anything with a Sub, it creates a Super, and so creates a foo. Then it looks at Sub itself, and creates another foo.

Now, when you cast sub as a Super, you're basicly telling java to ignore the fact that it's actually a Sub, and treat it as a Super, and so it does, it gets Super's variables, methods etc, and ignores anything you've re-defined in Sub.

If you created identically named methods in both Sub and Super, then whichever one got used woudl depend on what the object was cast as at the time. You can't cast it to a Super, and expect to access the Sub.

e.g.
Code:
class Super{ int foo=1; }
class Sub extends Super { int bar=2; }

Sub a=new Sub();
println(a.foo); //1
println(a.bar); //2

Super b=(Super)a;
println(b.foo); //1
println(b.bar); // ERROR Super doens't have a variable called bar

Re: Properties changing when casting Object
Reply #6 - Feb 24th, 2007, 2:35am
 
I agree that this all makes sense. Of course, methods and property declarations from the superclass should be used.

Still, I don't understand why this only happens if I redeclare a property in the subclass. Un-commenting the second declaration in this example leads to the unwanted result.

Code:

class Super
{
public String foo = new String("Super");
}

class Sub extends Super
{
//public String foo = new String("Sub");

Sub()
{
this.foo = "Sub";
}
}

Sub sub = new Sub();
Super subCast = (Super)sub;

println(sub.foo);
println(subCast.foo);
Re: Properties changing when casting Object
Reply #7 - Feb 24th, 2007, 2:42am
 
In the example, if you uncomment the line, but change the method to:

Code:
    Sub()
{
super.foo = "Sub";
}


Then it will change the value you see when you do println(subCast.foo);

Because they're 2 different foo variables, you have to state which one you want to change. this.foo refers only to the Sub.foo and will leave Super.foo alone with it's previous value, you have to explicitly change the Super value.

However back to your original problem, if you declare it final, you won't be able to change it.
Re: Properties changing when casting Object
Reply #8 - Feb 24th, 2007, 2:51am
 
OK, I think I'm enlightened for now. Thanks!
Page Index Toggle Pages: 1