如何实现构造函数扩展类

问题描述:

这工作:如何实现构造函数扩展类

class ABean implements A { 
    protected String field1; 
    ... 
    protected String fieldn; 

    public String getField1() { 
    return field1; 
    } 
    ... 
} 


class BBean extends ABean { 
    public BBean(A a) { 
    super(); 
    this.field1=a.getField1(); 
    ... 
    this.fieldn=a.getFieldn(); 
    } 
} 

但是写这个构造B(A a)很麻烦,不是真正实用,而且容易出错,因为如果我添加或A删除字段,然后我需要修改该构造函数,有时可能会忘记初始化A中的某些字段。

我想我可以为ABean实现克隆,但是会有类似的问题(因为在添加/删除字段时需要更新克隆实现)并且也不允许我有一个BBean(A a)构造函数;只有BBean(ABean a)构造函数,除非我也使clone()接口的一部分。

因此... 是否有更清洁,更好的实施方式BBean(A a)

+0

你有哪些类访问? A,ABean,BBean? – wmorrison365 2013-02-15 08:42:52

+0

@ wmorrison365我可以访问这两个课程。我开始意识到我可能会追逐鬼魂。毕竟,有很多方法可以显式地列出字段,比如equal,hashCode,toString甚至...并且在添加/删除新字段时需要修改这些方法。唯一的区别是这些方法可以使用Eclipse自动创建。所以没有神奇的项目符号,但有两种方法:明确列出所有的字段,并使用A建构方法移动A中的代码,您至少需要本地化字段更改或使用Edgard建议的反射。仍然想知道...... – Lolo 2013-02-15 17:23:23

而不是使用继承,请尝试使用组合。也就是说,而不是BBean extends ABean,使您的BBean有一个构造函数BBean(ABean a)。这样你就可以屏蔽掉如何在BBean的代码中构建新的ABean的所有细节。

+0

我假设你的意思是“让你的BBean有一个领域ABean,不是吗?是的,你是正确的,使用合成将解决我的问题。但不幸的是,我建立在已有的代码已经有一些对于使用继承的情况,我仍然需要一个解决方案 – Lolo 2013-02-14 17:33:33

+0

我接受你的答案,因为自从我写了这个问题后,我发现使用组合通常是最优雅地解决了这类问题的解决方案。 – Lolo 2013-04-17 14:40:32

什么如下实现你的ABean一个“A” -constructor(拷贝构造函数):

class ABean implements A { 
    protected String field1; 
    ... 
    protected String fieldn; 

    public String getField1() { 
     return field1; 
    } 
    ... 
    public ABean(A other) { 
     this.field1=other.getField1(); 
     ... 
     this.fieldn=other.getFieldn(); 
    } 
} 


class BBean extends ABean { 
    public BBean(A a) { 
     super(a); 
    } 
} 

通过这种方式,为A的你“拷贝构造函数”映射都在你的ABean。

+0

这有效,但有同样的问题,我试图解决。即:繁琐(必须明确写入所有领域),更重要的是,容易出错(如果我在A中添加一个字段并忘记更新ABean(A other),我会遇到麻烦 – Lolo 2013-02-14 17:35:52

+0

噢,我明白了,我假设你想要远离客户端类(例如BBean)本地化字段更改,以便您不必初始化值每。 – wmorrison365 2013-02-15 08:40:13

+0

好吧,所以不太漂亮,但在需要具有大量属性的大型BO的项目中很常见......您可以使用通用Map设置器给ABean一个值的映射)。它确保你的'BBean(A)'构造函数或者'ABean(A)'拷贝构造函数 - 不笨重,并且不会丢失新值。当然,这意味着你的BO不再是强类型的,并且不是很OO。当然,您可以使用真实访问器为基于Map的API补充众所周知的值。 – wmorrison365 2013-02-15 08:48:24

你可以使用反射:

class A {} 

class B { 
public B(A a) { 
    String methodName = null; 
    try { 
     Field[] fields = a.getClass().getDeclaredFields(); 
     for (Field field : fields) { 
      methodName = field.getName().substring(0, 1).toUpperCase() 
        + field.getName() 
          .substring(1, field.getName().length()); 
      field.get(a); 
      this.getClass().getMethod("set" + methodName, field.getClass()).invoke(a, field.get(a)); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

}

+0

好吧,这允许我不要每次在A中添加/删除字段时都重新编写该方法。我喜欢这样。但是阅读文档getDeclaredFields,它说它不会返回继承的字段。这似乎是一个问题。另外,如果A有吸气剂不可用的区域,我可能会遇到麻烦。我不太关心第二个问题(不太可能,并且可以通过为每个getMethod调用添加try/catch来解决),但第二个问题似乎是一个问题。 – Lolo 2013-02-14 17:45:12

+0

把这个方法放在类A中,并改变字段的值直接
'this.getClass()。getDeclaredFields()[0] .set(this,new String());'' – 2013-02-14 18:54:13