Reputation: 1188
Sorry if this has come up before, but I didn't see another thread about this. But if there is one, please give me the link.
Here I have a simple program. When it runs, it prints out " 6 4 "
public static void main(String[] args) {
Foo foo = new Foo();
foo.t = 6;
foo.f = 4;
Bar b = new Foo();
ArrayList<Bar> list = new ArrayList<Bar>();
list.add((Bar) foo);
Foo foo2 = (Foo) list.get(0);
System.out.println(foo2.t + " " + foo2.f);
}
static class Bar {
int t;
}
static class Foo extends Bar {
int f;
}
This seems strange, because I would think that when I added the Foo it to the list, it would remove the f field, as the list holds Bars, which don't have an f.
But it seems that the f is sticking around after being casted to a Bar. Could someone explain why this is?
Upvotes: 2
Views: 310
Reputation: 15644
In Java, fields are not polymorphic.
That's why your are confused about it.
So even if you add Foo
to the list, that f
is going to be there with it as its actaully an object of Foo
.
Following is taken from Code Ranch - by Jim Yingst
Is that by design in Java or a limition or my misunderstanding?
It's by design. Dynamic resolution of fields would make things run a little slower, and there's really no reason to need it, since you can make fields private and access them with method, which are dynamically resolved. So fields are resolved at compile time instead.
Upvotes: 1
Reputation: 2442
It's not how polymorphism works. It doesn't remove anything from particular object. You can think about it this way:
Every instance of Foo can be treated as instance of Bar. But after explicit cast you can act with this instance as Foo again. If it was originally Bar, then this cast will fail in Runtime.
Upvotes: 2
Reputation: 176
Its like when you type cast to the Super Class variable, you just can't access the sub-class properties of the object, But the object remains intact. Just the wrapper exposing the get() and set() methods
, is changed.
You will not be able to see the Sub-class getter-setter
method APIs.
But when you type cast back to the Sub-Class (Basically unwrapping), the sub-class getter setter methods are visible to you again.
The Object being unchanged the whole time.
Upvotes: 0
Reputation: 4004
Important addition to the previous answers: Adding an object to a list does not change that object in any way. So if there was an attribute in the object it remains intact.
The rest of the confusion is a feature called polymorphism. Since Foo is Bar you can always treat it as Bar, but since Foo is a modified (extended) Bar, it may behave differently from a standard Bar object.
I hope it helps.
Upvotes: 0
Reputation: 22710
Even if you cast and uncast it n number of times actual object will remain same.
Casting never add / removes / changes object attributes.
Bar b = new Foo();
Here reference is of type Bar
and actual object is of type Foo
. As Foo
extends Bar
which means it have the attribute f
and t
(Inherited from Bar
) as well.
list.add((Bar) foo);
Here you are casting it to Bar (Upasting) but actual object is not changed.
(Foo) list.get(0);
Here you are casting it back to Foo
still object is of type Foo
with original values for t
and f
.
Upvotes: 6