Modify the class FitnessExperiment class so that it uses polymorphism to:
(i) display the properties of each object in a FitnessExperiment, and
(ii) identify any StepsFitnessTracker, HeartRateFitnessTracker and
DistanceFitnessTracker objects that are equal. Here we are trying to identify those
cases where a user mistake might have been made during the initialisation of the
FitnessExperiment object (e.g. the data for the same tracker being introduced twice).
Those situations should be flagged to the person leading the experiment to verify if the error was
genuine or if the object was really the same object.
The area where the code needs to be implemeted will be in bold
We need to write a method that prints duplicates
FitnessExperiment.java
public class FitnessExperiment {
FitnessTracker[] fitnessTrackers;
public static void main(String[] args) {
FitnessTracker[] trackers = {
new StepsFitnessTracker("steps", new Steps(230)),
new StepsFitnessTracker("steps2", new Steps(150)),
new StepsFitnessTracker("steps2", new Steps(150)),
new HeartRateFitnessTracker("hr", new HeartRate(80)),
new HeartRateFitnessTracker("hr", new HeartRate(80)),
new DistanceFitnessTracker("dist2", new Distance(1000)),
new DistanceFitnessTracker("dist2", new Distance(2430)),
new DistanceFitnessTracker("dist2", new Distance(2430))
};
FitnessExperiment fe = new FitnessExperiment(trackers);
fe.printExperimentDetails();
}
// Constructor
public FitnessExperiment(FitnessTracker[] fitnessTrackers) {
this.fitnessTrackers = fitnessTrackers;
}
// Methods to implement:
// Implementation hint: Should it use the corresponding toString() methods for
// each of the objects stored in the fitnessTrackers array?
public String toString() {
// TODO Implement
String s = "";
for (FitnessTracker ft : fitnessTrackers) {
s = s + ft.toString() + "\n";
}
return s;
}
public void printExperimentDetails() {
System.out.print(this.toString());
System.out.println(fitnessTrackers.length + " number of fitness trackers are participated in this experiment");
System.out.println("Total number of steps : " + getTotalSteps());
System.out.println("Total number of steps : " + getTotalDistance());
}
// Method should iterate through all fitness tracker step measurements and returns a double
// with the total step count (see Task 2)
// Implementation hint: The instanceof operator and casting may become handy here
public int getTotalSteps() {
// TODO Implement
int totalSteps = 0;
for (FitnessTracker ft : fitnessTrackers) {
if (ft instanceof StepsFitnessTracker)
totalSteps = totalSteps + ((StepsFitnessTracker) ft).getTotalSteps().getValue();
}
return totalSteps;
}
// Method should iterate through all fitness tracker distance measurements and returns a double with the total distance
// Implementation hint: The instanceof operator and casting may become handy here
public double getTotalDistance() {
double totalDistance = 0;
for (FitnessTracker ft : fitnessTrackers) {
if (ft instanceof DistanceFitnessTracker)
totalDistance = totalDistance + ((DistanceFitnessTracker) ft).getTotalDistance().getValue();
}
return totalDistance;
}
public FitnessTracker[] getTrackersEqualTo(FitnessTracker tracker) {
int count = 0;
for(FitnessTracker fitnessTracker:fitnessTrackers){
if(fitnessTracker.equals(tracker))
count++;
}
FitnessTracker[] resultfitnessTrackers = new FitnessTracker[count];
int index = 0;
for(FitnessTracker fitnessTracker:fitnessTrackers){
if(fitnessTracker.equals(tracker))
resultfitnessTrackers[index++] = fitnessTracker;
}
return resultfitnessTrackers;
}
// Implementation hint: use the above getTrackersEqualTo() method
public void printAllEqualTrackers() {
// TODO Implement a method which prints every duplicate tracker
}
}
public class HeartRateFitnessTracker extends FitnessTracker {
HeartRate avgHeartRate;
int numMeasurements;
public HeartRateFitnessTracker(String modelName, HeartRate heartRate) {
super(modelName);
// Only one HeartRate to begin with; average is equal to single measurement
this.avgHeartRate = heartRate;
this.numMeasurements = 1;
}
public void addHeartRate(HeartRate heartRateToAdd) {
double newHR = heartRateToAdd.getValue();
double cmaHR = this.avgHeartRate.getValue();
double cmaNext = (newHR + (cmaHR * numMeasurements)) / (numMeasurements + 1);
this.avgHeartRate.setValue(cmaNext);
numMeasurements ++;
}
public HeartRate getAvgHeartRate() {
return avgHeartRate;
}
public String toString() {
return "Heart Rate Tracker " + getModelName() +
"; Average Heart Rate: " + getAvgHeartRate().getValue() +
", for " + numMeasurements + " measurements";
}
@Override
public boolean equals(Object obj) {
if(this == obj) // it will check if both the references are refers to same object
return true;
if(obj == null || obj.getClass()!= this.getClass()) //it check the argument of the type HeartRateFitnessTracker by comparing the classes of the passed argument and this object.
return false;
HeartRateFitnessTracker HRFT=(HeartRateFitnessTracker)obj; // type casting of the argument.
return (HRFT.avgHeartRate == this.avgHeartRate);// comparing the state of argument with the state of 'this' Object.
}
}
Extracted text: public class StepsFitnessTracker extends FitnessTracker { I/ Stores total number of steps private Steps totalSteps; public StepsFitnessTracker(String modelName, Steps steps) { super(modelName); this.totalSteps = steps; } I/ Add steps to the total public void addSteps(Steps stepsTOAdd) { int numSteps = this.totalSteps.getValue() + stepsToAdd.getValue(); this.totalSteps.setValue(numSteps); I/ Getter for total number of steps public Steps getTotalSteps() { return totalSteps; public String toString() { return "Steps Tracker " + getModelName() + "; Total Steps: "+ getTotalSteps().getValue(); @Override public boolean equals(Object obj) { II TODO Implement a method to check equality if(this == obj) // it will check if both the references are refers to same object return true; if(obj == null || obj.getClass()!= this.getClass()) //it check the argument of the type StepsFitnessTracker by comparing the classes of the passed argument and this object. return false; StepsFitnessTracker SFFT=(StepsFitnessTracker)obj; / type casting of the argument. if(SFFT.getTotalSteps() == this.totalSteps && this.totalSteps == null) return true; // check whether they both are null // check if one is null and other is not. if(SFFT.getTotalSteps() == null && this.totalSteps != null) return false; if(SFFT.getTotalSteps() != null && this.totalSteps == null) return false; // at the end check whether value of both are same. return (SFFT.getTotalSteps().getValue() == this.totalSteps.getValue();
Extracted text: public class DistanceFitnessTracker extends FitnessTracker{ private Distance distance; public DistanceFitnessTracker(String modelName, Distance distance) { super (modelName); this.distance = distance ; } public Distance getDistance() { return distance; } public void addDistance(Distance distance) { this.distance.setValue(this.distance.getValue() + distance.getValue()); } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getclass() != obj.getClass()) return false; if (!super.equals(obj)) return false; DistanceFitnessTracker that = (DistanceFitnessTracker) obj; if(this.getDistance() == null && that.getDistance() != nul1) return false; if(this.getDistance() != null && that.getDistance() == null) return false; if(that.getDistance() != this.getDistance()) return false; return that.getDistance().getValue() == this.getDistance().getValue(); }