Re: What do use instead of overriding static methods?
On Tue, 11 Aug 2009, Jim T wrote:
I'm extremely new to java, so I'm sure this has been asked before.
Please bear with me. Also please pardon any typos in my pseudocode.
Coming from Objective-C land, I have a class hierarchy and a bunch of
methods that basically amount to this:
class SuperClass {
Vector loadFromDatabase {
SomeVariable myType = CLASS.myType();
//load stuff up in an interesting manner
//return my vector
}
static int myType {
System.out.println("OH NOES!");
}
}
class Subclass1 extends SuperClass {
static int myType {return "foo"; };
}
class Subclass2 extends SuperClass {
static int myType {return "bar"; };
}
class Subclass3 extends SuperClass {
static int myType {return "baz"; };
}
//inside some method
Vector stuff = Subclass1.loadFromDatabase();
Essentially, the routine to load from the database is identical for
all subclasses, the only thing that needs to vary is what type of
object is getting loaded, and that's defined as a class method in the
subclass. All works wonderfully well in Objective-C, but, of course, I
have access to a class variable there (in an instance method "self" is
the object, in a static method, "self" is the class itself), so it's
easy to do.
And I'm just at a loss for a java-ish way to do this. I could define
some sort of lookup table in the superclass, but that's silly - and
requires the superclass to know which subclasses it has. But I can't
figure out any other way to do it. Once I'm in the loadFromDatabase()
method, it always seems to call SuperClass's myType().
So how can I implement this cleanly?
The thing is that classes in java are rather more static than they are in
objC, python, etc. Instead of putting the myType method in the class, you
need to factor it out into some other class, of which you can pass an
instance to the loadFromDatabase method. Or better yet, make
loadFromDatabase a method on that class. Something like:
abstract class Loader {
public List loadFromDatabase() {
String myType = myType();
// load stuff up in an interesting manner
// return my list
}
public abstract String myType();
}
class Subclass1Loader extends Loader() {
public String myType() {
return "foo";
}
}
class Subclass2Loader extends Loader() {
public String myType() {
return "bar";
}
}
This would be even better with some generics thrown in - put a type
variable T extends SuperClass on Loader, use it to parameterise the return
from loadFromDatabase, make the subclasses bind the variable in their
extends clauses, and then somehow work in a mechanism to ensure that the
loaded objects really are of the right type (which is the complicated
bit).
The meta-point is that you shouldn't try to translate from objC to java at
the level of statements; the two languages have different grain, and you
can't work with them in the same way any more than you could with bamboo
and mahogany.
tom
--
I think the Vengaboys compliment his dark visions splendidly well. -- Mark
Watson, on 'Do you listen to particular music when reading lovecraft?'