无法从 HashSet 中的类调用方法

发布于 2024-11-03 14:43:15 字数 2614 浏览 1 评论 0原文

我想做的是总结危险类别中的影响值,

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

下面有洞穴类危险类抽象占用者类

当向洞穴添加危险时,它就成为哈希集中的占用者。 当尝试使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

洒一地阳光 2024-11-10 14:43:15

另一种选择是将 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 可以让这变得简单,这是件好事。

Another option is to add the getImpact() method to Occupant, e.g.,

public double getImpact() {
    return 0.0;
}

whereas Hazard's @Override implementation of getImpact() would just return its impact instance variable as you already have it set up. Then, your loop is simplified to:

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

Should you need to extract to an appropriate interface abstraction later, it's a good thing modern IDEs make that easy.

又怨 2024-11-10 14:43:15

当迭代您的占用者时,您可以检查每个项目是否是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
    }
}

When iterating over your occupants you can check to see if each item is a Hazard like so:

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
    }
}
你的他你的她 2024-11-10 14:43:15

杰里米比我先一步。

然而,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.

隱形的亼 2024-11-10 14:43:15

我将在这里使用 访客模式

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;
  }
}

I would use the Visitor pattern here.

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;
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文