无法从HashSet中的类调用方法

时间:2011-04-28 02:27:19

标签: java double abstract hashset bluej

我想要做的是总结危险等级中的影响值

例如,它将查看占用者列表,发现危险并从中获取影响金额。然后总结所有危险的总影响并将该值返回给我。

下面我有 Cave类危险等级抽象占用者类

当向洞穴添加危险时,它将成为HashSet中的占用者。 当尝试使用getImpact()方法获取能量级别时,无法访问该方法,因为它位于Hazard而不是Occupant中。

我还有另外两个类也扩展了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;
}
}

4 个答案:

答案 0 :(得分:3)

另一种选择是将getImpact()方法添加到Occupant,例如

public double getImpact() {
    return 0.0;
}

Hazard @Override getImpact()的{​​{1}}实现只会返回它已设置的impact实例变量。然后,您的循环简化为:

public double getHazardEnergyImpacts() {
    double energyImpact = 0.0;
    for( Occupant occupant : occupants ) {
        energyImpact += occupant.getImpact();
    }
    return energyImpact;
}

如果您需要稍后提取到适当的接口抽象,那么现代IDE可以轻松实现这一点。

答案 1 :(得分:1)

在对occupants进行迭代时,您可以检查每个项目是否为Hazard,如此:

for(Occupant occupant : occupants){
    if(occupant instanceof Hazard){
        Hazard hazard = (Hazard) occupant; // now it's safe to cast
        double impact = hazard.getImpact();
        // do what you want with impact
    }
}

答案 2 :(得分:0)

杰里米打败了我。

但是,instanceof并不总是最好的解决方案。但在这种情况下,这是一个修复。

我实际上建议在这里使用接口来代替使用抽象类。但是,如果必须使用抽象类,则更有效的方法是简单地创建要在子类中使用的抽象方法。你必须在每个孩子中都覆盖它们,但你不必在每种情况下都实现它们。

答案 3 :(得分:0)

我会在这里使用Visitor pattern

public interface Occupant {
  void interact(Player p);
}

public class Player {
  public void handleInteraction(Hazard hazard) {
    // add code here
  }
  public void handleInteraction(Person person) {
    // add code here
  }
}

public class Hazard implements Occupant {
  public void interact(Player p) {
    p.handleInteraction(this);
  }

  public double getImpact(){
    return this.impact;
  }
}