2011-04-28 21 views
0

我所试图做的是无法调用HashSet的内类的方法

类总结在危险的影响值,例如,它会经过乘客的名单,发现危险并获得影响从它的金额。然后总结所有危害的总体影响并将该价值返还给我。

下面我有洞穴类危险级别摘要乘员类

向洞穴添加危险时,它成为HashSet中的占有者。 当试图通过getImpact()方法获取能量级别时,该方法无法访问,因为它处于危险中而不是占用。

我有两个其他职业也延伸占用者。 玩家商品

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

回答

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

杰里米打败了我。

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

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

+0

我同意,但是出来一个主要的白板会议(以及对需求的更好理解),您仍然必须收集*的危害* – Jeremy 2011-04-28 02:56:17

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

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

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使其轻而易举。