【问题标题】:how to instantiate T type inside a template class如何在模板类中实例化 T 类型
【发布时间】:2013-12-11 09:15:24
【问题描述】:

我有一个抽象类 abstract class MathFunc,用于在其特定类 final class Rastrigin extends MathFuncfinal class Griewangk extends MathFuncfinal class Rosenbrock extends MatjFunc 中实现数学函数 Rastrigin、Griewangk 和 Rosenbrock。

到目前为止,这种类层次结构以及它们的定义方式完美无缺,因此我认为没有必要在这方面寻求改进。

现在我必须实现另一个类Generation,其中将包含一些ArrayLists,但问题是我需要对上述每个数学函数都有一个生成实现。 所以我需要类似的东西:

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子类的多个实例吗?或者多次将同一个实例(tp)添加到列表中是否正确?
  • @Thomas 我想将 Rastrigin 类型的第 10 代对象或 Rosenbrock 类型的 10 个对象等添加到列表中,但我不知道如何实例化它们。
  • @Thomas 请查看对您的答案的评论并为工厂模式提供一些解释。

标签: java oop


【解决方案1】:

如果您想重用MathFunc 的同一实例,我看不出您的代码有任何重大缺陷(除了Generation 的通用定义应该是Generation&lt;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());

如果您想在Generation 中使用MathFunc 的多个实例,您可能需要改用工厂模式。

工厂界面:

interface MathFuncFuncFactory<T extends MathFunc> {
  T createFunc();
}

然后添加 RastriginFactory implements MathFuncFuncFactory&lt;Rastrigin&gt; 等实现。

内部生成:

Generation(MathFuncFactory<T> factory) {
  for(int i = 0; i < PopSize; i++) {
        pop.add(factory.createFunc());
    }
}

构造函数调用:

Generation<Rastrigin> rastriginGen = new Generation<>(new RastriginFactory());

【讨论】:

  • 我真的很喜欢这个答案,非常感谢会尝试这两种解决方案!我真的忘记了工厂模式。
  • public interface MathFuncFactory &lt;T extends MathFunc&gt;() { T createFunc(); } 似乎有问题 错误出现在 请告诉我如何解决它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多