Лучший способ сделать это - задействовать объект, который знает, как спасти себя. Если вы все еще хотите использовать DataStore, вы можете сделать что-то вроде этого:
interface YourInterface {
void save();
}
interface Request<E extends YourInterface> {
E getValue();
}
class DataStore<E extends YourInterface> {
public void save(Request<E> r) {
r.getValue().save();
}
}
Вы просто должны убедиться, что каждый из ваших объектов затем реализует interface
и альт, у вас есть Дженерики и полиморфизм, хорошо играющие друг с другом.
ПРИМЕЧАНИЕ. При написании вашего (исправленного) вопроса вы не используете полиморфизм. Вы используете перегрузку. Перегрузка метода определяется во время компиляции, тогда как полиморфизм метода определяется во время выполнения. Это часть того, почему вы сталкиваетесь с этими трудностями.
Если вам действительно не нужен вышеупомянутый вид дизайна, в котором объекты выполняют всю работу по спасению себя, то, возможно, вы можете сделать что-то вроде этого (в качестве очень слабого примера):
interface YourInterface {
String serialize();
}
interface Request<E extends YourInterface> {
E getValue();
}
class DataStore<E extends YourInterface> {
public void save(Request<E> r) {
String value = r.getValue().serialize();
// Now do something with value to save to a datastore
}
}
Выше приведен слабый пример, но основная идея заключается в том, что объекты знают, как выполнять часть сериализации, которая отличается между объектами, и затем DataStore может выполнять работу, которая является общей для всех ваших объектов.
И да, вы правы (с неверной терминологией) - генерики не очень хорошо справляются с перегрузкой. Но они хорошо играют с полиморфизмом. Полиморфизм обычно лучший инструмент, чем перегрузка в любом случае.