2015-05-11 249 views
3

我有一个抽象类Specie,然后是类动物扩展物种,然后是我的动物类(例如羊)。在动物中,我有一种方法来检查两个物体是否在地图上的相同位置,如果它们是相同的类型(例如羊和羊)。Java创建新对象

如果是,它会创建另一只绵羊。我有与 问题,我想这样的事情

Specie new_specie = this; 

而且我有一个副本consturctor在我的羊类

 public Sheep(Sheep new_sheep){ 

    this(new_sheep.get_x(),new_sheep.get_y(), new_sheep.get_img()); 
} 

然后将其保存到其中包含的所有对象的数组

species[speciesAmount] = new_specie; 

但它只是保存在数组中的两个元素相同的对象

species[0] 
species[2] 

相同的对象。有任何想法吗?

但是还有一个问题,我将有更多类型的动物(公式狼)的,我不能做

new Specie(this) 

,因为它是一个抽象类。

如何让它调用正确的构造函数?

编辑。我解决了它,我使用了clone()方法。

+2

公羊(羊new_sheep){ 您是否看到这个问题?基本上,你需要有一个羊实例,以便能够创建一个... – Stultuske

+0

但还有另一个问题,我将有更多类型的动物(方程式狼),我不能做 new Specie(this) 因为它是一个抽象类,如何使它调用合适的consturcotr? – Cardano

+1

新的Specie(this)有点废话imho,只要使用克隆方法,如果你需要类似的东西。 – Stultuske

回答

3

Specie new_specie = this;只会创建一个名为new_specie的新参考,并让它指向与this相同的对象。因此species[speciesAmount] = new_specie;将分配相同的引用数组条目(这本身就是一个参考)。

您的代码根本不会调用复制构造函数。与C++在Java中调用拷贝构造函数必须是这样的:

Specie new_specie = new Sheep(this); 

顺便说一句,你可能想看看进入Clonable接口这是为了提供对象拷贝。

更新:关于你的第二个问题,解决方案取决于你想达到什么。如果您只是希望在其中有两个物种的场地上存在具体物种的副本,则可以比较两个物种的类别(使用getClass()方法)或使用equals()检查相等性(取决于您如何定义该物种,它往往不止是平等的课程)。

然后,你基本上只是打电话Species new_species = species_on_field.clone()并获得克隆该领域之前的东西。

另一种选择可能是使用工厂模式或基于该领域当前物种种类的原型。尽管如此,我会留下这些给你看。

2

在Java中,您无法使用任务调用复制构造函数。你必须打电话给它!

species[0] = new Sheep(this); 
1

您可以通过比较其类,如种类比较:

if (specieA.getClass() == specieB.getClass) { 

然后,你的下一个步骤是创建一个新的物种。在运行时,您可以使用反射来访问这些信息。这是不是真的美丽的东西,但有时无法避免(例如,你不希望创建一个开关的情况下,每种):

Class<?> clazz = specieA.getClass(); 
    Specie newSpecie = clazz.getConstructor(clazz).newInstance(specieA); 
} 

这看起来对specieA的类的构造函数(名为clazz中这里)接受一个clazz实例作为它的输入参数。这样你就可以克隆任何东西(当然它有一个拷贝构造函数)。如果没有,则会抛出异常(您需要尝试捕获)。