我有一个抽象类abstract class MathFunc
,用于在其特定类final class Rastrigin extends MathFunc
,final class Griewangk extends MathFunc
和final class Rosenbrock extends MatjFunc
中实现数学函数Rastrigin,Griewangk和Rosenbrock。
到目前为止,这种类层次结构以及它们的定义是完美无缺的,因此我认为没有必要在这方面寻求改进。
现在,我必须实现另一个将包含某些Generation
的类ArrayLists
,但问题是,我需要为上述每个数学函数提供一个Generation实现。
所以我需要这样的东西:
ArrayList<Rastrigin> rast = new ArrayList<>();
ArrayList<Griewangk> grie = new ArrayList<>();
ArrayList<Rosenbrock> rose = new ArrayList<>();
在这些列表中,我需要实例化一些Rastrigin / Griewangk / Rosenbrock对象。
从过去的C ++项目知道,我可以使用模板来指定通用数据类型,并且我认为这是我的解决方案。到目前为止,我的实现如下所示:
public class Generation <MathFunc> {
private final ArrayList<MathFunc> pop = new ArrayList<>();
private final ArrayList<MathFunc> nextpop = new ArrayList<>();
private final ArrayList<MathFunc> Crossover = new ArrayList<>();
Generation(MathFunc tp)
{
for(int i = 0; i < PopSize; i++)
{
pop.add(tp);
}
}
}
但是问题是:我可以使用抽象类实例化依赖它的对象吗?还有另一种方法吗?我对模板的使用感到很困惑。
但是对我来说,做
Generation(Mathfunc tp)
似乎有点奇怪,因为抽象类无法实例化。附言This似乎是一个可能的解决方案,但我不确定它或它实际上如何工作。
最佳答案
如果要重用MathFunc
的相同实例,我的代码中看不到任何重大缺陷(除了Generation
的通用定义应为Generation<T extends MathFunc
)。
因此,首先像这样更改您的班级:
public class Generation <T extends MathFunc> {
private final ArrayList<T> pop = new ArrayList<>();
private final ArrayList<T> nextpop = new ArrayList<>();
private final ArrayList<T> Crossover = new ArrayList<>();
Generation(T tp) {
for(int i = 0; i < PopSize; i++) {
pop.add(tp);
}
}
}
然后像这样实例化
Generation
:Generation<Rastrigin> rastriginGen = new Generation<>(new Rastrigin());
Generation<Griewangk> griewangkGen = new Generation<>(new Griewangk());
Generation<Rosenbrock> rosenbrockGen = new Generation<>(new Rosenbrock());
如果要在
MathFunc
中使用Generation
的多个实例,则可能要使用工厂模式。工厂界面:
interface MathFuncFuncFactory<T extends MathFunc> {
T createFunc();
}
然后添加诸如
RastriginFactory implements MathFuncFuncFactory<Rastrigin>
等的实现。内部一代:
Generation(MathFuncFactory<T> factory) {
for(int i = 0; i < PopSize; i++) {
pop.add(factory.createFunc());
}
}
构造函数调用:
Generation<Rastrigin> rastriginGen = new Generation<>(new RastriginFactory());