What do use instead of overriding static methods?

J

Jim T

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?

While I'm at it, is there any way to dynamically choose a class to
call a class method upon? Again, in objective-C, you can do:

[[self class] someClassMethod];

So I'd think that the java equivalent would be:

this.getClass.someClassMethod();

But, alas, that doesn't seem to work either. Is this possible? And, if
so, how?

Many thanks,

-Jim...
 
M

markspace

Jim said:
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:


I agree with Eric. You ask for forgiveness for errors, but your errors
are so many that heck greatly impedes understanding. I can't really
tell what the heck you are after here. Some general concepts:


1. Static members are never inherited or overridden. I think that's at
least 50% of the trouble you are having right there. Java is similar to
C++ in this regard. Objective-C is off on some side road if it allows
inheritance of static members.

2. The normal way of handling this is just with regular old inheritance.

class SuperClass {
Map loadFromDatabase() {
//... load
return map;
}
}

3. If you cannot override the main method, create an overridable helper
method that you can.

class SuperClass {
final Map loadFromDatabase() {
//... load
map = loadHelper();
return map;
}
protected Map loadHelper() {
// more loading
return map;
}
}

class SubClass extends SuperClass {
protected Map loadHelper() {
// change loading behavior here
return map;
}
}

4. If you need to access a "type," you code is usually broken. Convert
access to the type into polymorphic method calls.

5. You can change the return type to a co-variant in Java 5 and later.
Co-variant means "sub-class." So if your super class has a method:

Object[] getRow() {...}

A sub-class can change this to:

String[] getRow() {...}

because String is a sub-class of Object. "getRow()" is still
overridden, not overloaded, which is usually desirable.

6. The fact that the database is the same and might be stored as a
static variable doesn't change any of the above. Accessing a static
(singleton) object doesn't change, as long as that object is thread
safe. Don't use static methods just because the variable is static, you
probably should use instance methods instead to get the correct
overriding behavior.


While I'm at it, is there any way to dynamically choose a class to
call a class method upon? Again, in objective-C, you can do:

[[self class] someClassMethod];


As Eric says, don't do this. See note 4 above: convert this selection
based on type to a polymorphic method call.

superClass.someInstanceMethod();
subClass.someInstanceMethod();
 
T

Tom Anderson

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
 
M

Mike Schilling

Jim said:
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:
[snip]

I can't really follow this, but I think it menas "I can read some
token from the database that tells me what sort of object to create."
If so, in Java that would be the fully qualified class name, and you'd
call

Class.forName(fullyQualifiedClassName).newInstance()
While I'm at it, is there any way to dynamically choose a class to
call a class method upon? Again, in objective-C, you can do:

[[self class] someClassMethod];

So I'd think that the java equivalent would be:

this.getClass.someClassMethod();

But, alas, that doesn't seem to work either. Is this possible? And,
if
so, how?

You'd have to use reflection, which is generaly considered a bad idea
except when strictly necessary. I'll go with the usual: don't ask us
how to do "X" in Java, tell us what you're trying to accomplish. (OK,
I'll say one lower-level thing: if a method should be called via
virtual dispatch, make it an instance method whether it uses "this" or
not. Occastionally I've had to use the pattern

class Z extends Y
{
public method()
{
return method_static();
}

public static method_static()
{
...
}
}

which allows the method to be called either statically or via an
instance. It's always been when I'm generating code, so the
maintenance issue of having to keep this in sync across the hierarchy
hasn't been an issue.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,979
Messages
2,570,185
Members
46,721
Latest member
NelsonHeil

Latest Threads

Top