Re: cast to sub-class or extending instance of super or a.n.other
On Sun, 12 Apr 2009, Richard Maher wrote:
I have an instance O of class A and I want to add a couple of attributes to
it
Can't be done. In java, by the time you have an instance, it's waaay too
late to add more attributes. In java, the set of attributes is defined
by the class, which is defined at compile-time; when you have an instance,
it's runtime, by which point the class definitions are set in stone.
Actually, you can define new classes at runtime, but it's a pain to do,
and anyway, you can't change the class of an object once it's made, so
that wouldn't help you anyway.
I'm guessing you have a backgrouns in a more dynamic language, like python
or javascript, where you can add fields willy-nilly.
At the moment I have a new class B that has variable instance of A and
instances of my other stuff, but in the ArrayList I only want to
remove(),contains() and so on, purely on the instance of A. I can
override the equals() and hashCode() methods in B to only check against
A and ignore the other stuff but ArrayList.mostMethods(o2) tend to use
the o2.equals(E) approach which isn't helpful.
I'm not sure what you mean by "o2.equals(E)", but this approach can
definitely be made to work, and is the java-esque way of doing it. If the
problem is that the list is calling methods on the object it contains
rather than the object you pass in, the solution is very simple - make
sure the object it contains is one of your objects too. That is, don't put
in Dogs and then try and remove Dalmatians, but make sure you always put
in Dalmatians (or whatever). So:
public class OriginalThing {}
public class ThingWithMinimumMessageNumber {
private OriginalThing thing;
private int minimumMessageNumber;
public ThingWithMinimumMessageNumber(OriginalThing thing, int minimumMessageNumber) {
this.thing = thing;
this.minimumMessageNumber = minimumMessageNumber;
}
public boolean equals(Object obj) {
if (!obj instanceof ThingWithMinimumMessageNumber) return false;
ThingWithMinimumMessageNumber that = (ThingWithMinimumMessageNumber)obj
return this.thing.equals(that.thing);
}
}
public class ThingManager {
private List<ThingWithMinimumMessageNumber> things;
public void put(OriginalThing thing, int minimumMessageNumber) {
things.add(new ThingWithMinimumMessageNumber(thing, minimumMessageNumber));
}
public boolean contains(OriginalThing thing) {
return things.contains(new ThingWithMinimumMessageNumber(thing, -1));
}
// etc
}
As I said this has gotta be easier than this so please put me out of my
misery. What's the best way of "new O = instance of A + stuff. Then
still behave like A in Arrays/Collections)
Basically can't be done.
However ...
You mention you're using JSObject. In that case, you can just do:
JSObject thing;
int minimumMessageNumber;
thing.setMember("minimumMessageNumber", new Integer(minimumMessageNumber));
In java terms, you haven't changed the set of attributes on the object.
But in javascript terms, you have. This might be enough for what you want
to do.
tom
--
Coldplay is the kind of music computers will make when they get smart
enough to start making fun of humans -- Lower Marsh Tit