Java使用正确对象的方法

Java使用正确对象的方法,java,arrays,Java,Arrays,这可能是非常明显的事情,但我真的在努力解决这个问题,任何帮助都将不胜感激 我正在尝试制作一个具有活动类的程序,它是运行游泳循环类的超类,还有一个类叫做member 成员有一个名为“日记”的arraylist,它记录成员所做的距离 private ArrayList<Activity>diary = new ArrayList<>(); 现在,我需要获得数组中每个类的距离,并显示每种类型的活动所涵盖的正确距离,我尝试了以下操作: public double[] getT

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

我正在尝试制作一个具有
活动
类的程序,它是
运行
游泳
循环
类的超类,还有一个类叫做member

成员有一个名为“日记”的arraylist,它记录成员所做的距离

 private ArrayList<Activity>diary = new ArrayList<>();
现在,我需要获得数组中每个类的距离,并显示每种类型的活动所涵盖的正确距离,我尝试了以下操作:

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;
   }
然后java抱怨这些类型不兼容:

incompatible types. required: run, found: activity.
如果run是activity的一个子类,那么为什么它会抱怨不兼容呢? 我如何让它使用正确的方法(“run”类中的getDistance方法)


谢谢

您已经以
ArrayList
的形式键入了您的列表
日记
,这意味着它包含类型为
活动
的元素。然后,假设列表中包含
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(); 
}
你做了三次同样的计算!您所做的只是为
活动
实例(
r
c
s
)指定了不同的名称,因此无法确定它是什么类型的活动。您可以像这样执行
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();
    }
}
这会起作用,但不是很优雅。相反,让对象告诉您它是什么类型。创建一个名为
ActivityType
enum
,并让抽象
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();
    }
}

你不能这样继承遗产。运行时不会从
日志中未运行的
内容中过滤掉所有
运行

您应该使用
instanceof
操作符执行以下操作

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

diary
包含类型为
Activity
,而不是
Run
”的对象,但这只返回超类的getDistance()方法“不,它不会”。它将返回对象实际是其实例的任何对象的
getDistance
。引用的类型并不重要。
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();
    }
}
for (Activity r: diary){
    if(r instanceof Run){
        distance[0] += r.getDistance(); 
    }
}