java, initialize SubClass from SuperClass
Solution 1
If you have a List<Base>
, then you cannot convert it to a List<SubClass>
. This is mainly because the list may not contain instances of SubClass
. The best you can do is:
List<SubClass> newList = new List<SubClass>();
for(Base b: list){
if (b instanceof SubClass) {
SubClass sub = (SubClass)b;
. . .
newList.add(sub);
}
}
Generally, however, when you find yourself doing this kind of thing, there's something wrong with your design. You might want to avoid subclassing Base
and using composition instead.
EDIT Based on your comments, it sounds like you want to construct a list of SubClass
instances using a list of Base
instances as a start. One approach is to define a constructor for SubClass
that takes a Base
as an argument.
public class SubClass extends Base{
private boolean selected;
public SubClass() {
// default constructor
}
public SubClass(Base original) {
// copy constructor -- initialize some fields from
// values in original, others with default values
}
...
getter und setter
...
}
Then you can construct your new list with:
List<SubClass> newList = new List<SubClass>();
for(Base b: list){
SubClass sub = new SubClass(b);
. . .
newList.add(sub);
}
Solution 2
There is a way: Various Java Beans spec based manipulation.
For example:
for( Base base: list ){
SubClass sub = new SubClass();
PropertyUtilsBean.copyProperties( sub, base );
if(...){
sub.setSelected(true);
}
newList.add(sub);
}
This works based on get/setters of the same name. Doesn't copy internal fields.
If you needed to copy internal fields, it's actually not that hard to implement using javax.lang.reflect
.
Solution 3
You appear to have a class with a lot of attributes and no easy way of setting them all. You have now run in to a problem where you need a class with an additional attribute but you have to deal with that mess of a base class.
I suggest that, instead of creating a subclass and casting, you create a wrapper class around the ugly one:
public class BigDumbClass {
// A lot of attributes
// No Constructor
// No init method
}
public class Wrapper {
private BigDumbClass base;
private boolean selected;
public Wrapper(BigDumbClass base) {
this.base = base;
this.selected = false;
}
//getters and setters
}
Now when you have to create that new list you can wrap everything in the old list
List<BigDumbClass> oldList = someData();
List<Wrapper> wraps = aNewList();
for (BigDumbClass bigDumb : oldList) {
Wrapper wrap = new Wrapper(bigDumb);
if (someCondition()) {
wrap.setSelected(true);
}
wraps.add(wrap);
}
Ideally, BigDumbClass would implement an interface that Wrapper could also implement, allowing the wrapper to defer all of the calls to the instance it has wrapped.
public class BigDumbClass implements SharedInterface {
// All the stuff outlined above
}
public class Wrapper implements SharedInterface {
// All the stuff outlined above
// Methods defined in SharedInterface
public void doSomething() {
base.doSomething();
}
}
Otherwise, you can provide a getter to the instance and access it directly.
BigDumbClass base = wrapper.getBase();
base.doSomething();
Rami.Q
Updated on July 09, 2022Comments
-
Rami.Q almost 2 years
public class Base { //long list of attributes // no Constructor using fields // no init methode // i cannot change this class }
now i extended the Base Class like:
public class subClass extends Base{ private boolean selected; ... getter und setter ... }
i become a list of Base object
List<Base>
but i need the same list but as
List<SubClass>
is there a way to initialize the Subclass from the Base Class?example:
for(Base b: list){ SubClass sub = (SubClass)b; // Thats wrong i know if(...){ sub.setSelected(true); } newList.add(sub); }
i try to avoid the manual init of each Attribute of the Base
Class
to the SubClassi update my Question as requested in the Comments: the Design above is just an example. my QUESTIN EXACTLY IS:
why converting BaseClass into SubClass (sence
Subclass extends BaseClass
) is not Possible? why Java dosn't allow me to do the following:example:
Class Base{ private String name; ..... } Class SubClass extends Base{ private String title; }
then
Base b = DBController.getById(...); SubClass sub = (SubClass)b;
after that the Object
sub
should have the Attribute Name from the Objectb
and thetitle
Attribute is nullwhy is this not the case in java?
sorry for my bad english, thanks
-
Rami.Q about 11 yearsthanks for the answer. the List has only Objects type of Base, so these are no instances of Subclass in the list. but why casting the Class is wrong? attributes in the SubClass could be null after casting, the i can set it manualy like in my example above. what do you tink about that?
-
Rami.Q about 11 yearsi mean, after casting SubClass should have all attributes of the Base Class and the rest Attributes in SubClass would be null
-
Ted Hopp about 11 years@Rami.Q - Okay, your comments clarified to me something about what you want. I revised my answer to address this.
-
Rami.Q about 11 yearsthanks for your answer. i accepted it, because i do it this way. but its still not the best solution. Oracle should give us an auto Conversion from Base Class into SubClass. something like Attributes UNION.
-
Jake Greene about 11 yearsJust because you have a reference for a super class does not mean you are pointing to a super class. 'Base baseRef' may be pointing to a SubClass1, so 'SubClass2 subRef = (SubClass2)baseRef' is not a valid cast.