Re: cast to sub-class or extending instance of super or a.n.other
Hi Tom,
"Tom Anderson" <twic@urchin.earth.li> wrote in message
news:alpine.DEB.1.10.0904121526410.25482@urchin.earth.li...
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.
Ok, thanks.
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.
Just happy to learn off people who could know more than me.
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)",
This from JavaDocs ArrayList.remove()
Removes a single instance of the specified element from this list, if it is
present (optional operation). More formally, removes an element e such that
(o==null ? e==null : o.equals(e)),
<<<<<<<<<<<<<<<
I'm just whining that in a perfect world it would say "e.equals(o)".
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));
}
As I said somewhere above, contains() and indexOf() seem to be fine by
overriding equals() and yes the others like remove() can be handled like: -
return things.remove(new ThingWithMinimumMessageNumber(thing)).
No one else seems to have a problem with it so I guess that's as good as it
gets?
// 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.
Certainly looks that way.
However ...
You mention you're using JSObject. In that case, you can just do:
JSObject thing;
int minimumMessageNumber;
thing.setMember("minimumMessageNumber", new
Integer(minimumMessageNumber));
Good point, the SetMember can be done up front and there's also similar
stuff going on there. But seems like a fair bit of additional o/head to ask
JavaScript to getMember for each incoming message. Still, maybe it can be
moved down a bit and combined later with the first callback. Sounds
promising. . .
Nah, scrub that. The validation should be done in the Applet.
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
Cheers richard Maher
--
Coldplay is the kind of music computers will make when they get smart
enough to start making fun of humans -- Lower Marsh Tit