0

这可能是非常明显的事情,但我真的在努力解决这个问题,任何帮助将不胜感激。

我正在尝试制作一个具有Activity类的程序,该类是类的超Run Swim Cycle类,并且还有另一个类称为成员。

成员有一个名为 diary 的数组列表,用于记录成员的距离

 private ArrayList<Activity>diary = new ArrayList<>();

活动添加如下:

 public void addActivity(Activity a){
    diary.add(a);

 }

现在我需要将每个类的距离放入一个数组中并显示每种活动所涵盖的正确距离,我尝试这样做:

public double[] getTotalDistances(){
   double distance[];
   distance = new double[3];


    for (Activity r: diary){
           distance[0] += r.getDistance(); 
    }
    for(Activity c: diary ){
           distance[1] += c.getDistance(); 
    }

    for(Activity s: diary ){
           distance[2] += s.getDistance(); 
    }

    for(int i = 0; i < distance.length; i++){
        System.out.println(distance[i]);

    }




    return distance;
   }

但这仅返回超类的 getDistance() 方法,如果我这样做:

for (Run r: diary){
           distance[0] += r.getDistance(); 
    }

然后java抱怨那些是不兼容的类型:

incompatible types. required: run, found: activity.

如果 run 是活动的子类,那么它为什么会抱怨不兼容呢?以及如何让它使用正确的方法(“运行”类中的 getDistance 方法)

谢谢!

4

2 回答 2

2

您已经将列表键入diaryArrayList<Activity>,这意味着它包含 type 的元素Activity。然后,您通过假设列表包含Run项目来要求 Java 进行迭代,但事实并非如此。这是因为列表可以包含的任何子类,Activity假设一个是没有意义的。所以你真的不能做更多的事情:

for(Activity activity : diary) {
   ...
}

现在在以下三个循环中:

for (Activity r: diary){
       distance[0] += r.getDistance(); 
}

for(Activity c: diary ){
       distance[1] += c.getDistance(); 
}

for(Activity s: diary ){
       distance[2] += s.getDistance(); 
}

你在做同样的计算三遍!您所做的只是为Activity实例赋予不同的名称(rcs),因此您无法确定它是哪种活动。您可以instanceof像这样进行检查:

for (Activity activity : diary){
    if (activity instanceof Run) {
        distance[0] += activity.getDistance(); 
    } else if (activity instanceof Cycle) {
        distance[1] += activity.getDistance();
    } else if (activity instanceof Swim) {
        distance[2] += activity.getDistance();
    }
}

这会起作用,但不是很优雅。而是让对象告诉你它是什么类型。创建一个enum被调用ActivityType并让你的抽象Activity类有一个名为的方法getActivityType

public abstract class Activity {    
    ...
    ...

    public abstract ActivityType getActivityType();
}

然后每个子类都会实现这个方法并返回正确的类型:

public class Run extends Activity {
    ...
    ...

    @Override
    public ActivityType getActivityType() {
        return ActivityType.RUN;
    }
}

等等。

然后在你的循环中,你只需要这样做:

for (Activity activity : diary){
    if (activity.getActivityType() == ActivityType.RUN) {
        distance[0] += activity.getDistance(); 
    } else if (activity.getActivityType() == ActivityType.CYCLE) {
        distance[1] += activity.getDistance();
    } else if (activity.getActivityType() == ActivityType.SWIM) {
        distance[2] += activity.getDistance();
    }
}
于 2013-11-12T15:33:08.267 回答
0

你不能像这样进行继承。运行时不会过滤掉所有run不在run你的 s 中的 sdiary

您应该改为对操作员执行以下instanceof操作

for (Activity r: diary){
    if(r instanceof Run){
        distance[0] += r.getDistance(); 
    }
}
于 2013-11-12T15:34:07.190 回答