【问题标题】:Unable to call a method from classes within a HashSet无法从 HashSet 中的类调用方法
【发布时间】:2011-04-28 02:27:18
【问题描述】:

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

例如,它将遍历一个居住者列表,找到一个危险并从中获取影响量。然后将所有危害的总影响相加,并将该值返回给我。

下面是洞穴类危险类抽象居住者类

当向洞穴添加危险时,它会成为 HashSet 中的居住者。 尝试使用 getImpact() 方法获取能量级别时,无法访问该方法,因为它在 Hazard 而非 Occupant 中。

我还有另外两个类也扩展了 Occupant。 播放器物品

在添加到 HashSet 以便可以使用 getImpact() 方法时,我找不到将危险保留为 Hazard 类的方法。

在添加到 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;
}
}

【问题讨论】:

    标签: java double abstract hashset bluej


    【解决方案1】:

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

    public double getImpact() {
        return 0.0;
    }
    

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

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

    如果您以后需要提取到适当的接口抽象,现代 IDE 让这一切变得简单是件好事。

    【讨论】:

      【解决方案2】:

      当迭代您的 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
          }
      }
      

      【讨论】:

        【解决方案3】:

        杰里米打败了我。

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

        我实际上建议在这里为行为使用接口而不是使用抽象类。但是,如果必须使用抽象类,更有效的方法是简单地创建要在子类中使用的抽象方法。您必须在每个子项中全部覆盖它们,但不必在每种情况下都实现它们。

        【讨论】:

        • 我同意,但是如果没有主要的白板会议(以及对要求的更好理解),您仍然需要收集just危害的影响
        【解决方案4】:

        我会在这里使用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;
          }
        }
        

        【讨论】:

          猜你喜欢
          • 2019-06-16
          • 2022-08-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-12-06
          相关资源
          最近更新 更多