Java using method of the correct object

时间:2023-02-09 23:44:29

this might be something very obvious but i am really struggling with the problem, any help would be appreciated.

这可能是非常明显的事情,但我真的在努力解决这个问题,任何帮助都会受到赞赏。

i am trying to make a program that has an Activity class, which is a superclass for Run Swim Cycle classes, and there is another class called member.

我正在尝试创建一个具有Activity类的程序,它是Run Swim Cycle类的超类,还有另一个名为member的类。

a member has an arraylist called diary which keeps records of the distances made by a member

一个成员有一个名为diary的arraylist,它记录了一个成员所做的距离

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

activities are added like so:

活动是这样添加的:

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

 }

now i need to get the distances for each of the classes in to an array and display the correct distance covered in each type of activity, i tried doing this:

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

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;
   }

but this returns the getDistance() method of only the superclass, if i do this:

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

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

then java complains that those are incompatible types :

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

incompatible types. required: run, found: activity.

if run is a subclass of activity then why would it complain about incompatibility? and how do i get it to work with the correct method (the getDistance method that is in the "run" class)

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

THanks!

2 个解决方案

#1


2  

You already typed your list diary as ArrayList<Activity>, which means it contains elements of type Activity. Then you're asking Java to iterate by assuming that the list contains Run items, which it doesn't. This is because the list can contain any subclass of Activity and it doesn't make sense to assume one. So you really can't do more than:

您已经将列表日记键入为ArrayList ,这意味着它包含Activity类型的元素。然后你要求Java迭代,假设列表包含Run项目,而不是。这是因为列表可以包含Activity的任何子类,并且假设一个子列没有意义。所以你真的做不到:

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

Now in the following three loops:

现在在以下三个循环中:

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

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

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

You're doing the same calculation three times! All you've done is given different names to the Activity instances (r, c, and s) so there is no way you can figure out what kind of activity it is. You could do instanceof checks like so:

你做了三次相同的计算!你所做的一切都给了Activity实例(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();
    }
}

This would work, but isn't very elegant. Instead let the object tell you what type it is. Create an enum called ActivityType and have your abstract Activity class have a method called getActivityType:

这可行,但不是很优雅。而是让对象告诉你它是什么类型。创建一个名为ActivityType的枚举,让您的抽象Activity类有一个名为getActivityType的方法:

public abstract class Activity {    
    ...
    ...

    public abstract ActivityType getActivityType();
}

Then each subclass would implement this method and return the proper type:

然后每个子类将实现此方法并返回正确的类型:

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

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

and so on.

等等。

Then in your loop, you just need to do this:

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

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();
    }
}

#2


0  

You can't do inheritance like this. The runtime won't filter out all of the runs from the things that aren't runs in your diary

你不能这样做继承。运行时不会过滤掉日记中未运行的所有运行

you should instead do something like the following with the instanceof operator

你应该使用instanceof运算符执行类似下面的操作

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

#1


2  

You already typed your list diary as ArrayList<Activity>, which means it contains elements of type Activity. Then you're asking Java to iterate by assuming that the list contains Run items, which it doesn't. This is because the list can contain any subclass of Activity and it doesn't make sense to assume one. So you really can't do more than:

您已经将列表日记键入为ArrayList ,这意味着它包含Activity类型的元素。然后你要求Java迭代,假设列表包含Run项目,而不是。这是因为列表可以包含Activity的任何子类,并且假设一个子列没有意义。所以你真的做不到:

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

Now in the following three loops:

现在在以下三个循环中:

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

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

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

You're doing the same calculation three times! All you've done is given different names to the Activity instances (r, c, and s) so there is no way you can figure out what kind of activity it is. You could do instanceof checks like so:

你做了三次相同的计算!你所做的一切都给了Activity实例(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();
    }
}

This would work, but isn't very elegant. Instead let the object tell you what type it is. Create an enum called ActivityType and have your abstract Activity class have a method called getActivityType:

这可行,但不是很优雅。而是让对象告诉你它是什么类型。创建一个名为ActivityType的枚举,让您的抽象Activity类有一个名为getActivityType的方法:

public abstract class Activity {    
    ...
    ...

    public abstract ActivityType getActivityType();
}

Then each subclass would implement this method and return the proper type:

然后每个子类将实现此方法并返回正确的类型:

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

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

and so on.

等等。

Then in your loop, you just need to do this:

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

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();
    }
}

#2


0  

You can't do inheritance like this. The runtime won't filter out all of the runs from the things that aren't runs in your diary

你不能这样做继承。运行时不会过滤掉日记中未运行的所有运行

you should instead do something like the following with the instanceof operator

你应该使用instanceof运算符执行类似下面的操作

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