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)?

Was it helpful?

Solution

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.

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();
    }
}

}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top