2011-04-28 49 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使其輕而易舉。