我有一个抽象类Specie,然后是类动物,它扩展了物种,然后是我的动物类(例如绵羊)。在动物中我有一种方法可以检查两个物体是否在地图上的相同位置,以及它们是否是相同类型(例如绵羊和绵羊)。
如果是的话会造成另一只羊。我有问题 我尝试了类似的东西
Specie new_specie = this;
我的绵羊班有一个复制构件
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()方法。
答案 0 :(得分:3)
Specie new_specie = this;
只会创建一个名为new_specie
的新引用,并让它引用与this
相同的对象。因此species[speciesAmount] = new_specie;
将为数组条目(它本身就是一个引用)分配相同的引用。
您的代码根本不会调用复制构造函数。与Java中的C ++不同,调用复制构造函数必须如下所示:
Specie new_specie = new Sheep(this);
顺便说一下,你可能想看看Clonable
接口,它是为了提供对象复制。
更新:关于您的第二个问题,解决方案取决于您希望实现的目标。如果你只想要有两个物种的场上具体物种的副本,你可以只比较两个物种的类别(使用getClass()
方法)或使用equals()
检查相等性(取决于你如何定义它,它通常不仅仅是相同的类)。
然后你基本上只需要调用Species new_species = species_on_field.clone()
并获得之前该字段上的内容的克隆。
另一种选择可能是使用工厂模式或基于该领域当前物种类的原型。我会留下那些让你在网上查询。
答案 1 :(得分:2)
在Java中,您无法使用作业调用复制构造函数。你必须打电话给它!
species[0] = new Sheep(this);
答案 2 :(得分:1)
您可以通过比较他们的类来比较物种,例如:
if (specieA.getClass() == specieB.getClass) {
然后,您的下一步是创建一个新的物种。在运行时,您可以使用反射访问此信息。它并不是真正的美丽,但有时无法避免(例如,你不想为每个物种创建一个开关盒):
Class<?> clazz = specieA.getClass();
Specie newSpecie = clazz.getConstructor(clazz).newInstance(specieA);
}
这将查找specieA的类(此处命名为clazz)的构造函数,该构造函数接受clazz实例作为其输入参数。这样你就可以克隆任何东西(前提是它有一个拷贝构造函数)。如果没有,则会抛出异常(您需要尝试捕获)。