2

Let's say I have a base/main abstract class: AbstractObject. AbstractObject is extended by two classes: Object1 and Object2.

Those two templates have many different classes extending from them also, for instance, Object3, Object4, and Object5 are inheriting from Object1, and Object6, Object7 are inheriting from Object2.

I want each separate class (Object1, Object2, ..., Object7) to have a counter that counts the number of instances made of it.

I thought I could use some public static variable counter, but I am not sure how to declare it in AbstractObject, so none of my objects will copy the code. Any thoughts?

abstract class AbstractObject {
  ...
  public static counter = ?
}

class Object1 extends AbstractObject {
  ...
}

class Object2 extends AbstractObject {
  ...
}

class Object3 extends Object1 {
  ...
}

class Object4 extends Object1 {
  ...
}

class Object7 extends Object2 {
  ...
}
x80486
  • 6,627
  • 5
  • 52
  • 111
Yariv Levy
  • 162
  • 1
  • 9
  • 9
    You can't. Each class needs to have its own counter field (why should it be public?). Or you can use a single shared CountManager which would use some Map containing the count of each class. – JB Nizet Dec 28 '18 at 17:24
  • 4
    That said, why do you want to count instances of a class? What concrete problem are you trying to solve? – JB Nizet Dec 28 '18 at 17:27
  • Just to clarify, you want a separate counter for each object (i.e. 3 `Object1`, 2`Object2`, etc.), and NOT a counter that counts how many of every type has been made in total (i.e. 20 Objects)? – Stalemate Of Tuning Dec 28 '18 at 17:29
  • @JBNizet Exactly, a different counter for each different class – Yariv Levy Dec 28 '18 at 17:45

2 Answers2

2

I want ... to have a counter that counts the number of instances made of it.

Instances - that mean "objects instatiated for each class" ?
If yes, then use a static map. For example:

public class AbstractObject {

    private static Map<Class, Integer> map = Collections.synchronizedMap(new HashMap<>());

    public AbstractObject() {
        Class clazz = this.getClass();
        map.merge(clazz, 1, (x, y) -> x + y);
    }

    public static Map<Class, Integer> getCounters() {
        return Collections.unmodifiableMap(map);
    }
}

public class Object1 extends AbstractObject {
}

public class Object11 extends Object1 {
}

public class Object2 extends AbstractObject {
}

public class Object12 extends Object11{
}

And now:

public static void main(String[] args) {
    AbstractObject o1 = new Object1();
    o1 = new Object1();
    o1 = new Object2();
    o1 = new Object11();
    o1 = new Object11();
    o1 = new Object12();

    AbstractObject.getCounters().forEach((k, v) -> System.out.println(k + " ==> " + v));
}

gives this result:

class somepackage.Object11 ==> 2
class somepackage.Object12 ==> 1
class somepackage.Object1 ==> 2
class somepackage.Object2 ==> 1
krokodilko
  • 35,300
  • 7
  • 55
  • 79
  • Yes, and you could use an abstract method that each class would have to implement to get its own record count from the static map. – Gus Dec 28 '18 at 18:29
0

You have to have a static field count in each class. If we have a static field only in AbstractObject class, it will NOT be inherited to other classes (because it is static).

To count the number of objects of each class, you have to use a "factory" method (like getNewInstance() in below example).

public abstract class AbstractObject {
  public static void main(String[] args) {
    Object1 a = Object1.getNewInstance();
    Object2 b = Object2.getNewInstance();
    Object2 c = Object2.getNewInstance();

    System.out.println("Number of Object1 instances = " + Object1.getCount());
    System.out.println("Number of Object2 instances = " + Object2.getCount());
  }
}

class Object1 extends AbstractObject {
  private static int count;

  private Object1() {
  }

  static Object1 getNewInstance() {
    count++;
    return new Object1();
  }

  static int getCount() {
    return count;
  }
}

class Object2 extends AbstractObject {
  private static int count;

  private Object2() {
  }

  static Object2 getNewInstance() {
    count++;
    return new Object2();
  }

  static int getCount() {
    return count;
  }
}
Prasad Karunagoda
  • 2,048
  • 2
  • 12
  • 16