0

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.

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

 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:

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

then java complains that those are incompatible types :

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)

THanks!

2
  • diary contain objects of type Activity, not Run. Commented Nov 12, 2013 at 15:24
  • "but this returns the getDistance() method of only the superclass" No, it won't. It will return getDistance of whatever the object is actually an instance of. The type of the reference doesn't matter. Commented Nov 12, 2013 at 15:39

2 Answers 2

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:

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:

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:

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();
    }
}
Sign up to request clarification or add additional context in comments.

Comments

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

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.