Java 如何在一个专门的子类中坚持DRY的原则?
我想用N个字段创建一个类,然后用N-1个字段创建它的子类,在子类中,第一个字段应该填充到构造函数中。以下是最简单的示例:Java 如何在一个专门的子类中坚持DRY的原则?,java,oop,Java,Oop,我想用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 ThreeT
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
s创建一个方法-它返回一个新的Thing
,并在b
中添加1
public Thing transform() {
return new Thing(this.a, this.b + 1);
}
但是,当此方法被继承到ThreeThing
中时,返回的对象仍然是Thing
而不是ThreeThing
,因此我必须重写ThreeThing
中的方法。这不是什么大问题,但在我的项目中,会有很多专门的东西s,如果行为是相同的,我不想覆盖所有这些方法
以下是我想到的可能的解决方案,没有一个能让我满意
- 为
Thing
和ThreeThing
创建一个方法clone
,将字段复制到一个新实例,然后使用反射来改变私有字段以获得所需的结果。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()
,如果您发现自己正在使用它,您可能需要备份一些步骤,检查总体设计,看看是否可以改进。例如,我添加了一个copy()
方法,该方法应该在子类中被重写。您可以只使用克隆而不使用反射
具有的层次结构中的每个非抽象类都有一个克隆方法,该方法创建一个实例并将其传递给另一个克隆成员的克隆方法。层次结构中的抽象类将只有仅克隆成员的受保护方法
例如,在子类ThreeThing
中,您将有:
public Object clone ()
{
ThreeThing
thing = new ThreeThing ();
clone (thing);
return thing;
}
protected void clone (Thing other)
{
super.clone (other);
ThreeThing
thing = (ThreeThing) other;
thing.some_member = this.some_member;
....
}
记住实现Cloneable
@whowantsakookie我同意,我只是没有包含完整的类定义。(应该避免)当某个\u成员
是一个私有字段时,这怎么可能起作用?@itdoesnwork它起作用,因为您是从引入它的同一类访问私有字段的clone
ofThreeThing
只克隆ThreeThing
引入的成员,clone
ofThing
只克隆Thing
引入的成员,等等……这几乎是我的总体设计。您有什么改进的建议吗?在我看来,在子类中实现transform()
,或者在每个子类中创建一个copy()
,并在transform
中使用它会更有意义