无法从 HashSet 中的类调用方法
我想做的是总结危险类别中的影响值,
例如它将遍历居住者列表,找到危险并从中获取影响量。然后将所有危险的总影响相加,并将该值返回给我。
下面有洞穴类、危险类和抽象占用者类。
当向洞穴添加危险时,它就成为哈希集中的占用者。 当尝试使用 getImpact() 方法获取能量水平时,无法访问该方法,因为它是在 Hazard 而不是 Occupant 中。
我还有另外两个类也扩展了占用者。 玩家和物品。
在添加到 HashSet 时,我找不到一种方法将危险保留为危险类,以便可以使用 getImpact() 方法。
当添加到 HashSet 时,这还需要满足其他类 Player 和 Item 的需要。
public class Cave {
HashSet<Occupant> occupants;
private double impact;
/**
* Creat a new Cave instance with no occupants.
*/
public Cave()
{
occupants = new HashSet<Occupant>();
}
/**
* Adds an occupant to a Cave if the occupant is not already there and
* if cave currently has fewer than the maximum number of occupants.
* @param occupant, the occupant to add
* @return true if successfully added
*/
public boolean addOccupant(Occupant occupant) {
boolean validNewOccupant = occupant != null;
boolean enoughRoom = occupants.size() < MAX_OCCUPANTS;
if (validNewOccupant && enoughRoom) {
validNewOccupant = occupants.add(occupant);
}
return validNewOccupant && enoughRoom;
}
/**
* Gets the sum of the impact from all hazards in the cave
* @returns hazardEnergyImpact
*/
public double getHazardEnergyImpacts(){
double energyImpact = 0.0;
for( Occupant occupant : occupants ){
if(occupant.toString() == "!"){
energyImpact += occupant.getImpact();
}
}
return energyImpact;
}
}
public abstract class Occupant {
private Address address;
private String name;
/**
* Construct an occupant for a known address & name.
* @ param row, row of address
* @ param column, row of address.
* @ param name, occupant's name
*/
public Occupant(Address address, String name) {
this.address = address;
this.name = name;
}
@Override
public String toString(){
return "";
}
}
public class Hazard extends Occupant {
private String longDescription;
private double impact;
/**
* Construct a hazard with know attributes
* @param row
* @param column
* @param name
* @param longDescription
* @param impact
*/
public Hazard(Address address, String name, String longDescription, double impact) {
super(address, name);
this.longDescription = longDescription;
this.impact = impact;
}
@Override
public String toString(){
return "!";
}
/**
* gets impact amount
* @returns impact
*/
public double getImpact(){
return this.impact;
}
}
What I am trying to do is sum up the impact values in Hazard Class
For example it will go through a list of occupants, find a hazard and get the impact amount from it. Then sum the total impact of all hazards and return that value to me.
Below I have the Cave class, Hazard class and Abstract Occupant class.
When adding a hazard to the cave, it becomes an occupant in the HashSet.
When trying to get the energy levels with the getImpact() method, the method cannot be accessed as it is in Hazard and not Occupant.
I have two other classes that also extend of Occupant. Player and Item.
I cannot find a way to keep the hazard as a Hazard class when adding to the HashSet so that getImpact() method can be used.
This also needs to cater for the other classes Player and Item when adding to the HashSet.
public class Cave {
HashSet<Occupant> occupants;
private double impact;
/**
* Creat a new Cave instance with no occupants.
*/
public Cave()
{
occupants = new HashSet<Occupant>();
}
/**
* Adds an occupant to a Cave if the occupant is not already there and
* if cave currently has fewer than the maximum number of occupants.
* @param occupant, the occupant to add
* @return true if successfully added
*/
public boolean addOccupant(Occupant occupant) {
boolean validNewOccupant = occupant != null;
boolean enoughRoom = occupants.size() < MAX_OCCUPANTS;
if (validNewOccupant && enoughRoom) {
validNewOccupant = occupants.add(occupant);
}
return validNewOccupant && enoughRoom;
}
/**
* Gets the sum of the impact from all hazards in the cave
* @returns hazardEnergyImpact
*/
public double getHazardEnergyImpacts(){
double energyImpact = 0.0;
for( Occupant occupant : occupants ){
if(occupant.toString() == "!"){
energyImpact += occupant.getImpact();
}
}
return energyImpact;
}
}
public abstract class Occupant {
private Address address;
private String name;
/**
* Construct an occupant for a known address & name.
* @ param row, row of address
* @ param column, row of address.
* @ param name, occupant's name
*/
public Occupant(Address address, String name) {
this.address = address;
this.name = name;
}
@Override
public String toString(){
return "";
}
}
public class Hazard extends Occupant {
private String longDescription;
private double impact;
/**
* Construct a hazard with know attributes
* @param row
* @param column
* @param name
* @param longDescription
* @param impact
*/
public Hazard(Address address, String name, String longDescription, double impact) {
super(address, name);
this.longDescription = longDescription;
this.impact = impact;
}
@Override
public String toString(){
return "!";
}
/**
* gets impact amount
* @returns impact
*/
public double getImpact(){
return this.impact;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
另一种选择是将
getImpact()
方法添加到 Occupant,例如,Hazard
的@Override
实现getImpact()
只会返回其impact
实例变量,因为您已经设置了它。然后,您的循环被简化为:如果您稍后需要提取到适当的接口抽象,那么现代 IDE 可以让这变得简单,这是件好事。
Another option is to add the
getImpact()
method to Occupant, e.g.,whereas
Hazard
's@Override
implementation ofgetImpact()
would just return itsimpact
instance variable as you already have it set up. Then, your loop is simplified to:Should you need to extract to an appropriate interface abstraction later, it's a good thing modern IDEs make that easy.
当迭代您的
占用者
时,您可以检查每个项目是否是Hazard
,如下所示:When iterating over your
occupants
you can check to see if each item is aHazard
like so:杰里米比我先一步。
然而,instanceof 并不总是最好的解决方案。但在这种情况下,这是一个修复。
我实际上建议在这里使用接口来实现行为,而不是使用抽象类。但是,如果必须使用抽象类,更有效的方法是简单地创建要在子类中使用的抽象方法。您必须在每个子项中重写它们,但不必在每种情况下都实现它们。
Jeremy beat me to it.
However, instanceof isn't always the best solution. In this case though, it's a fix.
I would actually recommend using interfaces here for the behaviors instead of using an abstract class. However, if you must use an abstract class, a more efficient way to do this would be to simply create abstract methods that you want to use in your child classes. You would have to override them all in each child, but you don't have to implement them in every case.
我将在这里使用 访客模式。
I would use the Visitor pattern here.