Имеется пара классов A и B, так что B extends A.
У этих классов разные по числу параметров конструкторы A(int a) и B(int a, int b).
Экземпляры этих классов создаются в результате парсинга строчек, так что:
A create(String s) {
// ...
return new A(a);
}
B create(String s) {
// ...
return new B(a, b);
}
Для удобства доступа есть желание поместить эти методы в некий общий класс Factory, чтобы эту фабрику можно было бы хранить в переменной и передавать в разные места как одно целое. Естественно, поместить в класс два метода, различающиеся лишь типом результата нельзя, но теоретически и по смыслу задачи можно специализировать вызовы для каждого случая использования.
Если брать C++, получается такое решение:
#include <iostream>
using namespace std;
class A {
public:
A(int a) {
cout << "A" << endl;
}
};
class B: public A {
public:
B(int a, int b): A(a) {
cout << "B" << endl;
}
};
class Factory {
public:
template<class T>
T *create() {
return new T();
}
template<>
A *create() {
return new A(0);
}
template<>
B *create() {
return new B(0, 1);
}
};
int main() {
Factory factory;
delete factory.create<A>();
delete factory.create<B>();
return 0;
}
В данном случае используется механизм специализации шаблона. Для каждого вызова create из main по шаблонному параметру выбирается, какую из трёх реализаций выбирать: обобщённую (generic) для неизвестных типов, либо одну из специализированных, если параметром задан класс A или B. В специальных реализациях вызываются нужные конструктры (со своим количеством параметров для каждого случая).
В Java некоторые элементы специализации шаблонов имеются. В Java можно написать нечто вида X<T extends U> или для метода <T extends U>T f(). Но компилятор либо не использует информацию об ограничении типа параметра generic-типа или -функции, либо я чего-то не знаю. Можно ли такое сделать?
P.S. Варианты с использованием Reflections и RTTI (конструкции наподобие instanceof или if(x.class == ...) ) не предлагать. Хочется иметь "автоматический" выбор нужной реализации фабричного метода на этапе компиляции.