无法调用HashSet的内类的方法
问题描述:
我所试图做的是无法调用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;
}
}
答
当遍历您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
}
}
答
杰里米打败了我。
但是,instanceof并不总是最好的解决方案。但在这种情况下,这是一个解决方案。
我实际上建议在这里使用接口来代替使用抽象类的行为。但是,如果您必须使用抽象类,则更有效的方法是简单地创建要在子类中使用的抽象方法。您必须在每个孩子中都覆盖他们,但是您无需在每种情况下都实施它们。
答
我会在这里使用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;
}
}
答
另一种选择是将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使其轻而易举。
我同意,但是出来一个主要的白板会议(以及对需求的更好理解),您仍然必须收集*的危害* – Jeremy 2011-04-28 02:56:17