我想用N个字段创建一个类,然后用N-1个字段将其子类化,并且在子类中,第一个字段应填充到构造函数中。这是最简单的示例:

class Thing {
    protected int a;
    protected int b;

    public Thing(int a, int b) {
        this.a = a;
        this.b = b;
    }
}

class ThreeThing extends Thing {
    public ThreeThing(int b) {
        this.a = 3;
        this.b = b;
    }
}

现在,我想为所有Thing的方法都遵循不可变性-它返回一个新的Thing,在b中添加了1。
public Thing transform() {
    return new Thing(this.a, this.b + 1);
}

但是,当此方法继承到ThreeThing中时,返回的对象仍然是Thing而不是ThreeThing,因此我必须重写ThreeThing中的方法。这不是什么大问题,但是在我的项目中,将有很多专门的Thing,如果行为是相同的,我不想在所有方法中都覆盖该方法。

这是我想到的可能解决方案,没有一个能让我满意
  • cloneThing制作一个ThreeThing方法,该方法将字段复制到新实例,然后使用反射对私有(private)字段进行突变以获得所需的结果。 ThreeThing唯一需要的方法是clone
  • 只需使用反射即可使用新值
  • 实例化getClass()的结果

    有没有没有反射的方法或更好的设计对象的方法?

    最佳答案

    由于父级不能直接实例化子级(因为它不“知道”它),因此可以使用反射来做到这一点:

    class Thing {
        protected int a;
        protected int b;
    
        public void setB(int b) {
            this.b = b;
        }
    
        public void setA(int a) {
            this.a = a;
        }
    
        public Thing(){}
    
        public Thing(int a, int b) {
            this.a = a;
            this.b = b;
        }
    
        Thing copy() {                  // adding a copy method
            return new Thing(a, b);
        }
    
        public Thing transform() throws IllegalAccessException, InstantiationException {
            // Thing result = (Thing)this.getClass().newInstance(); // one way to do it (reflection)
            Thing result = copy(); // a better way to do it
            result.setA(a);
            result.setB(b+1);
            return result;
        }
    
        public static void main(String[] args) throws InstantiationException, IllegalAccessException {
            ThreeThing x = new ThreeThing(1);
            System.out.println(x.a + " : " + x.b);
            Thing y = x.transform();
            System.out.println(y.a + " : " + y.b);
        }
    }
    
    class ThreeThing extends Thing {
    
        public ThreeThing(){}
    
        ThreeThing(int b) {
            this.a = 3;
            this.b = b;
        }
    
        @Override
        Thing copy() {           // adding a copy method
            return new ThreeThing(b);
        }
    }
    

    就是说,它是使用newInstance()better to avoid,如果您发现自己在使用它,则可能需要备份一些步骤并检查总体设计,看看是否可以改进。例如,我添加了copy()方法,该方法应在子类中被覆盖。

    09-28 05:01