【问题标题】:Is there any way to mimic class-instance-variable concept from Ruby in Java?有没有办法在 Java 中模仿 Ruby 中的类实例变量概念?
【发布时间】:2019-06-30 08:27:55
【问题描述】:

假设我有一个 Animal 类,以及它的两个子类,即 Dog 和 Cat。我想记录 Dog 和 Cat 类的实例(例如 {Dog: 3, Cat: 1})。

class Animal{
  static int instances = 0;
  public Animal(){
    instances++;
  }
}

我可以使用Animal.instances 来计算所有动物的数量。但是,我想分别获得每种动物的计数。如何在不重复所有子类的构造函数中的相同代码的情况下实现这一点?

【问题讨论】:

    标签: java oop


    【解决方案1】:

    不要依赖静态或reflexively checking the class name

    解决此问题的最佳方法是将创建对象的责任推给工厂:

    interface AnimalFactory<T extends Animal>
    {
        T create();
    }
    
    interface CountingAnimalFactory<T extends Animal> extends AnimalFactory<T>
    {
        int numberOfAnimals();
    }
    
    public class CountingDogFactory implements CountingAnimalFactory<Dog>
    {
        private int numberOfDogs;
    
        public Dog create() {
            numberOfDogs++;
            return new Dog();
        }
    
        public int numberOfAnimals() {
             return numberOfDogs;
        }
    }
    

    您可以将 DogCat 的构造函数设置为包私有,以强制它们通过工厂实例化。

    【讨论】:

      【解决方案2】:

      你可以维护一张地图:

      class Animal {
      
          static Map<String, Long> counts = new HashMap<>();
      
          public Animal() {
              counts.compute(this.getClass().getName(), 
                      (s, old) -> old == null ? 1 : old + 1);
          }
      }
      

      如果您预见到竞争条件,那么您可能应该将counts 设为ConcurrentHashMap

      【讨论】:

      • 以上所有答案都可以,但不要忘记,如果你重新定义无参数构造函数,你将不得不这样做:class Cat extends Animal { public Cat(Arg arg){ super() ; } }
      【解决方案3】:

      这样的事情可能会有所帮助:

      class Animal {
          static Map<Class, Integer> instances = new HashMap<>();
      
          public Animal() {
              if (instances.get(this.getClass()) == null)
                  instances.put(this.getClass(), 0);
              instances.put(this.getClass(), instances.get(this.getClass()) + 1);
          }
      }
      

      现在,如果您想获取 Cats 的数量,请使用 instances.get(Cat.class)

      【讨论】:

        猜你喜欢
        • 2010-09-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-15
        • 2010-09-06
        • 2012-12-25
        相关资源
        最近更新 更多