Let's say we have a class SCORE. It has three objects s1,s2 and s3. SCORE has an attribute RUNS. How to add the runs of all the objects ? SCORE has an internal method int TOTALSCORE(). so when that method is called, it should return the total score .
How should i call that method ? Like s1.TOTALSCORE() ? Or any other way?
In rare cases the thing that you want could be reasonably, but normally the class is not aware of all it's elements. A total Score is for a Collection of Score elements, maybe a List or a Set.
So you would do:
class Score {
int value;
// ...
public static int totalScore(Collection<Score> scores){
int sum = 0;
for (Score s: scores){
sum += s.value;
}
return sum;
}
}
And outside you would have
List<Score> myBagForScores = new ArrayList<>();
Score e1 = new Score...
myBagForScores.add(e1);
// e2, e3 and so on
int sum = Score.totalScore(myBagForScores);
Hope that helps!
Here is a small Proof-Of-Concept:
public class Score {
private static ReferenceQueue<Score> scoreRefQueue = new ReferenceQueue<Score>();
private static List<WeakReference<Score>> runs = new ArrayList<WeakReference<Score>>();
static { // remove references to instances that are Garbage Collected
new Thread(new Runnable() {
@Override
public void run() {
while(true) try {
Object scoreRef = scoreRefQueue.remove(); // blocks until next reference is available
synchronized(runs) { // synch access with summing iterator
runs.remove(scoreRef);
}
} catch(Throwable t) {
// ignore
}
}
}).start();
}
/**
* The factory method
*/
public static Score getInstance() {
final Score score = new Score();
final WeakReference<Score> scoreRef = new WeakReference<Score>(score, scoreRefQueue);
synchronized(runs) {
runs.add(scoreRef);
}
return score;
}
private int total;
private Score() {
// prevent creating instances outside this class
}
/**
* The service method
*/
public static int totalScore() {
int totalScore = 0;
synchronized(runs) { // synch access with cleanup thread
for(WeakReference<Score> scoreRef : runs) {
final Score score = scoreRef.get();
if(score != null) {
totalScore += score.total;
}
}
}
return totalScore;
}
}
The idea is not to allow creating instances outside your factory method #getInstance(). The instances are tracked using WeakReferences to allow their Garbage Collection. The list is update by a service thread waiting on the reference queue. Hope this helps.