Хотя я полностью согласен с тем, что «Статика - это неправильная вещь, которую нужно использовать здесь», я вроде понимаю, что вы пытаетесь рассмотреть здесь. Тем не менее, поведение экземпляра должно быть способом работы, но если вы настаиваете на этом, я бы поступил так:
Начиная с вашего комментария "Мне нужно создать его экземпляр, чтобы получить строку, которая действительно статична в поведении"
Это не совсем правильно. Если вы хорошо выглядите, вы не меняете поведение своего базового класса, а просто изменяете параметр для метода. Другими словами, вы меняете данные, а не алгоритм.
Наследование более полезно, когда новый подкласс хочет изменить способ работы метода, если вам просто нужно изменить «данные», которые класс использует для работы, возможно, такой подход поможет.
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;
}
}
То есть сопоставить все операторы с картой. «Очевидный» следующий шаг к этому - загрузить карту из внешнего ресурса, такого как файл свойств, или XML, или даже (почему нет) таблицы базы данных, для дополнительной гибкости.
Таким образом, вы сможете порадовать своих учеников (и себя), потому что вам не нужно «создавать экземпляр» для выполнения работы.
// Client usage:
...
List albums = ModelBase.findAll( Album.class );
...
Другой подход заключается в создании экземпляров сзади и сохранении целостности вашего клиентского интерфейса при использовании методов экземпляров. Метки помечаются как «защищенные», чтобы избежать внешнего вызова. Аналогично предыдущему образцу вы можете сделать это
// 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";
}
}
И вам не нужно менять клиентский код, и при этом вы все еще обладаете способностью полиморфизма.
// Client usage:
...
List albums = ModelBase.findAll( Album.class ); // Does not know , behind the scenes you use instances.
...
Надеюсь, это поможет.
Последнее замечание об использовании List и ArrayList. Всегда лучше программировать на интерфейс, чем на реализацию, таким образом вы делаете свой код более гибким. Вы можете использовать другую реализацию List, которая работает быстрее или делает что-то еще, не изменяя ваш клиентский код.