Instead of using inheritance, try using composition. That is, instead of BBean extends ABean
, make your BBean
have a constructor BBean(ABean a)
. That way you've shielded yourself from all the details of how to construct a new ABean
in BBean
's code.
How to implement constructor for extended class
-
09-03-2022 - |
Question
This works:
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();
}
}
But writing this constructor B(A a)
is cumbersome, not really practical, and error prone because if I add or remove fields in A
, then I need to modify that constructor and may sometimes forget to initialize some of the fields present in A
.
I suppose I could implement clone for ABean, but that would have similar issues (because the clone implementation would need to be updated when I add/remove fields) and that would also not allow me to have a BBean(A a)
constructor; only a BBean(ABean a)
constructor unless I make the clone()
part of the interface also.
So... is there a cleaner, better way of implementing BBean(A a)
?
Solution
OTHER TIPS
What about implementing an "A"-constructor (copy-constructor) on your ABean as follows:
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);
}
}
This way, your "copy-constructor" mapping for A's is all in your ABean.
you can use reflection:
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();
}
}
}