Альтернативы для абстрактного статического / статического переопределения методов с обобщениями в Java - PullRequest
1 голос
/ 09 декабря 2011

Хорошо, я знаю, что у вас не может быть абстрактного статического метода, хотя я считаю это ограничением лично.Я также знаю, что переопределение статических методов бесполезно, потому что, когда я имею дело с, скажем, MyList<T extends ObjectWithId> и у моего объекта есть абстрактный класс со статическим методом, который переопределяется в его подклассах, T не существует во время выполнения, поэтому ObjectWithIdСтатический метод будет вызываться вместо подкласса.

Итак, вот что у меня есть:

class PersistentList<T extends ObjectWithId> implements List<T>{

}

, где ObjectWithId:

abstract ObjectWithId{
    public abstract long getId();
}

Теперь проблемазаключается в том, что мой PersistentList предназначен для хранения на жестком диске, отсюда и название, и в действительности он будет хранить только идентификаторы объектов, которые он содержит.Теперь, когда я хочу реализовать

@Override
public T get(int index) {

}

метод PersistentList, я хочу, чтобы моя программа использовала id, который она хранила для index, и вызывала статический метод objectForId(long id)который будет реализован в каждом подклассе ObjectWithId.Это не может быть метод экземпляра, потому что еще нет экземпляра, смысл в том, чтобы загрузить экземпляр с жесткого диска, используя id.Так как это должно быть реализовано?Один из вариантов заключается в том, чтобы ObjectWithId имел конструктор ObjectWithId(long id), реализованный в каждом подклассе, но T не существует во время выполнения, так как бы я его создал?Я знаю, что мог бы передать Class<T> объект в конструкторе PersistentList, но я бы предпочел, чтобы конструктор не имел никаких аргументов, но я не думаю, что есть способ получить класс T без явной передачи его вверно?

Надеюсь, это лучшее объяснение, извините за неоднозначный вопрос, с которого я начал.

Ответы [ 2 ]

1 голос
/ 10 декабря 2011

Передача Class<T> в качестве аргумента конструктора не решит вашу проблему.После этого у вас будет доступ к классу, но для получения доступа к статическому методу, определенному в классе, вам придется использовать дженерики (если кто-то еще не знает, как вызвать статический метод, определенный для класса, из объекта Class).

Я бы определил новый универсальный интерфейс, который содержит универсальный метод objectForID, что-то вроде

public interface ObjectRetriever<T>{
  public T objectForID( long aID );
}

, и настроил бы конструктор PersistentList так, чтобы такой экземпляр ObjectRetriever принимался как параметр,Этот ObjectRetriever может затем использоваться для восстановления объектов на основе их идентификатора.

1 голос
/ 09 декабря 2011

Хотя всегда кажется, что начинать со статических методов всегда легче, я обнаружил, что обычно полезно избегать статических методов именно по этой причине и использовать методы экземпляра по умолчанию.

Преимуществоэто расширяемость.Помимо возможности наследования и исключения упомянутых «ограничений», он обеспечивает расширяемость - без необходимости переделывать вещи и изменять API позже.Например, «этот класс делает именно то, что мне нужно, но я бы хотел изменить только эту часть функциональности».Если есть статические методы, вызывающие другие статические методы, то нет хорошего способа сделать это.Если все методы нестатические - я могу создать подкласс этого класса и переопределить только ту часть функциональности, которая требуется.

Другое (несколько связанное) ограничение статических методов заключается в том, что их нельзя использовать для реализации.интерфейсы.

Таким образом, я предпочитаю зарезервировать статические методы для "служебных методов", где выполняемая ими функция действительно ясна, и в будущем нет никакой реальной причины, по которой понадобится альтернативная реализациябудет предоставлено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...