我想创建一个具有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;
}
}
现在,我想为所有尊重不变性的东西制作一个方法 – 它返回一个新的东西,其中1添加到b.
public Thing transform() {
return new Thing(this.a, this.b + 1);
}
但是,当此方法继承到ThreeThing时,返回的对象仍然是Thing而不是ThreeThing,因此我必须覆盖ThreeThing中的方法.这不是一个大问题,但在我的项目中,会有很多专门的东西,如果行为是相同的话,我不想在所有这些方法中覆盖该方法.
以下是我想到的可能的解决方案,他们都没有满足我
>为Thing和ThreeThing创建方法克隆,将字段复制到新实例,然后使用反射来改变私有字段以获得所需的结果. ThreeThing中唯一需要的方法是克隆.
>只需使用反射来使用新值实例化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()方法,应该在子类中重写.