Albeit, I totally agree in the point of "Static is the wrong thing to be using here", I kind of understand what you're trying to address here. Still instance behavior should be the way to work, but if you insist this is what I would do:
Starting from your comment "I need to create an instance of it just to get a string that is really static in behaviour"
It is not completely correct. If you look well, you are not changing the behavior of your base class, just changing the parameter for a method. In other words you're changing the data, not the algorithm.
Inheritance is more useful when a new subclass wants to change the way a method works, if you just need to change the "data" the class uses to work probably an approach like this would do the trick.
class ModelBase {
// Initialize the queries
private static Map<String,String> selectMap = new HashMap<String,String>(); static {
selectMap.put( "Album", "select field_1, field_2 from album");
selectMap.put( "Artist", "select field_1, field_2 from artist");
selectMap.put( "Track", "select field_1, field_2 from track");
}
// Finds all the objects for the specified class...
// Note: it is better to use "List" rather than "ArrayList" I'll explain this later.
public static List findAll(Class classToFind ) {
String sql = getSelectSQL( classToFind );
results = execute( sql );
//etc...
return ....
}
// Return the correct select sql..
private static String getSelectSQL( Class classToFind ){
String statement = tableMap.get( classToFind.getSimpleName() );
if( statement == null ) {
throw new IllegalArgumentException("Class " +
classToFind.getSimpleName + " is not mapped");
}
return statement;
}
}
That is, map all the statements with a Map. The "obvious" next step to this is to load the map from an external resource, such as a properties file, or a xml or even ( why not ) a database table, for extra flexibility.
This way you can keep your class clients ( and your self ) happy, because you don't needed "creating an instance" to do the work.
// Client usage:
...
List albums = ModelBase.findAll( Album.class );
...
Another approach is to create the instances from behind, and keep your client interface intact while using instance methods, the methods are marked as "protected" to avoid having external invocation. In a similar fashion of the previous sample you can also do this
// Second option, instance used under the hood.
class ModelBase {
// Initialize the queries
private static Map<String,ModelBase> daoMap = new HashMap<String,ModelBase>(); static {
selectMap.put( "Album", new AlbumModel() );
selectMap.put( "Artist", new ArtistModel());
selectMap.put( "Track", new TrackModel());
}
// Finds all the objects for the specified class...
// Note: it is better to use "List" rather than "ArrayList" I'll explain this later.
public static List findAll(Class classToFind ) {
String sql = getSelectSQL( classToFind );
results = execute( sql );
//etc...
return ....
}
// Return the correct select sql..
private static String getSelectSQL( Class classToFind ){
ModelBase dao = tableMap.get( classToFind.getSimpleName() );
if( statement == null ) {
throw new IllegalArgumentException("Class " +
classToFind.getSimpleName + " is not mapped");
}
return dao.selectSql();
}
// Instance class to be overrided...
// this is "protected" ...
protected abstract String selectSql();
}
class AlbumModel extends ModelBase {
public String selectSql(){
return "select ... from album";
}
}
class ArtistModel extends ModelBase {
public String selectSql(){
return "select ... from artist";
}
}
class TrackModel extends ModelBase {
public String selectSql(){
return "select ... from track";
}
}
And you don't need to change the client code, and still have the power of polymorphism.
// Client usage:
...
List albums = ModelBase.findAll( Album.class ); // Does not know , behind the scenes you use instances.
...
I hope this helps.
A final note on using List vs. ArrayList. It is always better to program to the interface than to the implementation, this way you make your code more flexible. You can use another List implementation that is faster, or does something else, without changing your client code.