user2209644
user2209644

Reputation: 711

Java using method of the correct object

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!

Upvotes: 0

Views: 69

Answers (2)

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

Upvotes: 0

Vivin Paliath
Vivin Paliath

Reputation: 95598

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

Upvotes: 2

Related Questions