2013-02-27 2 views
2

я следующий интерфейс определен:Создание класса с общими типами во время выполнения

public interface AllImplementMe<X, Y> { 
    public Y doSomething(X param); 
} 

Теперь я хочу, чтобы определить фабричный метод, который нужно построить суб-классы для выше во время выполнения.

public static <X,Y> AllImplementMe<X, Y> createInstance(String xClassName, String yClassName) { ... } 

Как мне на самом деле запрограммировать вышеуказанный метод? Я искал API отражения, но не смог понять это? Предполагается, что все подкласс имеют конструктор по умолчанию.

Edit1

Я просто хочу, чтобы добавить некоторые разъяснения относительно намерений вышеуказанного кода. Вышеупомянутая часть является частью общей системы, которая позволит добавлять новые вспомогательные классы во время выполнения и выполняться на основе конфигурации, определенной извне. Таким образом, на самом деле фабричный метод будет вызываться на основе этой конфигурации и построить соответствующий дочерний объект, который затем будет просить выполнить их методы. Это концептуально похоже на AsyncTask от Adnroid http://developer.android.com/reference/android/os/AsyncTask.html с проблемой, что мне нужно создать реализацию объектов дочернего класса в общем виде. В большинстве случаев основной код, который будет называть этих детей, не связан с их параметрами.

+0

Вы ищете анонимный класс? – sp00m

+0

А какова роль 'X param' в методе' doSomething'? – sp00m

ответ

2

Используйте следующий фабричный метод вместо:

public static <X, Y> AllImplementMe<X, Y> createInstance(Class<X> xClass, Class<Y> yClass) 

Затем вы можете использовать такие вещи, как xClass.newInstance() создать экземпляр X. (Я не написал точный код, так как не знаю, что вы хотите делать с X и Y.)

+0

Когда он (она) говорит о подклассе, не означает ли это какой-то класс, реализующий «AllImplementMe»? – Apurv

+0

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

+1

Я предлагаю стандартный способ предоставления этих классов, и он менее подвержен ошибкам (и IDE будет лучше поддерживать вас, если вы используете рефакторинг), если вы используете 'MyClass.class' вместо строки типа' 'com.myclass .MyClass "'. Вызывающий должен уже знать классы, чтобы использовать возвращаемый тип. Вы можете использовать 'Class.forName (xClassName)', но тогда вам нужно будет использовать его или использовать класс Class.asSubclass', который является некстати, особенно если имена классов, которые они указали в качестве параметров, фактически не соответствуют X и Y. –

1

Все намного проще. Вам даже не нужны эти параметры String xClassName, String yClassName.

Рассмотрит вас есть реализация вашего интерфейса:

public class SomeImplementation<A,B> implements AllImplementMe<A,B> { 
    @Override 
    public B doSomething(A param) { 
     //  ... blablabla ... 
    } 
} 

Тогда ваш статический фабричный метод будет просто:

public static <A, B> AllImplementMe<A, B> createInstance() { 
    return new SomeImplementation<A,B>(); 
} 
+0

Сам метод Factory, относящийся к подклассу, является более обходным путем. Реализация фабричного метода должна быть общей, так что все дочерние классы не должны просто реализовывать фабричный метод и возвращать свой экземпляр из него. Я предпочитаю не использовать наследование, когда композиция может больше отвечать за нее! –

+0

О, дорогая, вы не можете использовать переменные типа класса в объявлении статического метода.Вы уверены, что хорошо разбираетесь в теории дженериков? – Andremoniy