我想用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
,如果行为是相同的,我不想在所有方法中都覆盖该方法。这是我想到的可能解决方案,没有一个能让我满意
clone
和Thing
制作一个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()
方法,该方法应在子类中被覆盖。