我想要做的是总结危险等级中的影响值
例如,它将查看占用者列表,发现危险并从中获取影响金额。然后总结所有危险的总影响并将该值返回给我。
下面我有 Cave类,危险等级和抽象占用者类。
当向洞穴添加危险时,它将成为HashSet中的占用者。 当尝试使用getImpact()方法获取能量级别时,无法访问该方法,因为它位于Hazard而不是Occupant中。
我还有另外两个类也扩展了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;
}
}
答案 0 :(得分:3)
另一种选择是将getImpact()
方法添加到Occupant,例如
public double getImpact() {
return 0.0;
}
而Hazard
@Override
getImpact()
的{{1}}实现只会返回它已设置的impact
实例变量。然后,您的循环简化为:
public double getHazardEnergyImpacts() {
double energyImpact = 0.0;
for( Occupant occupant : occupants ) {
energyImpact += occupant.getImpact();
}
return energyImpact;
}
如果您需要稍后提取到适当的接口抽象,那么现代IDE可以轻松实现这一点。
答案 1 :(得分: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
}
}
答案 2 :(得分:0)
杰里米打败了我。
但是,instanceof并不总是最好的解决方案。但在这种情况下,这是一个修复。
我实际上建议在这里使用接口来代替使用抽象类。但是,如果必须使用抽象类,则更有效的方法是简单地创建要在子类中使用的抽象方法。你必须在每个孩子中都覆盖它们,但你不必在每种情况下都实现它们。
答案 3 :(得分: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;
}
}