Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid code duplication in overloaded constructors?

Say that I have one constructor that takes an input and another that uses a default value. Both constructors then proceed to process this data in exactly the same way. (Example below.) What are my options to avoid code duplication in this case?

(I've read the post how to reduce the code of constructor overloading, where the top answer suggests using the keyword "this". In my case, I guess I would need to use "this" to call the first constructor from the second one after the input has been stored. This however results in a compilation error: "call to this must be first statement in constructor".)

Example code:

public class A {
  public A(String a) {
    //process a
  }
  public A() {
    String a = "defaultString";
    //process a
  }
}

EDIT: I'm taking a lot of fire for using an input dialog call in a class constructor (which I'm aware isn't exactly good practice). So I've changed the code example to direct the discussion away from this :).

like image 575
andreasdr Avatar asked May 07 '12 21:05

andreasdr


4 Answers

One way is to have an init method:

public class A {
    public A(String a) {
        init(a);
    }
    public A() {
        String a = "defaultString";
        init(a);
    }
    private void init(String a) {
        //process a
    }
}
like image 61
assylias Avatar answered Oct 17 '22 17:10

assylias


Say that I have one constructor that takes an input and another that asks for it via an input dialog.

Don't do that. It will make for horribly entangled and hard to maintain code in the long run. At least try to seperate UI concerns (input dialogs etc) from your object model (which you can feed a string in the constructor).

In my honest opinion you really don't want an overloaded constructor here.

like image 39
ChristopheD Avatar answered Oct 17 '22 17:10

ChristopheD


You may want to try chaining your constructors:

public class A {
  public A(String a) {
    //process a
  }
  public A() {
    this("defaultString");
  }
}

If you want to use a dialog to get the string, I recommend you present the dialog before calling this constructor.

like image 41
Chuck Krutsinger Avatar answered Oct 17 '22 18:10

Chuck Krutsinger


I think this is the preferred method:

public class A {
  public A(String a) {
    //process a
  }
  public A() {
    this(JOptionPane.showInputDialog("a"));
  }
}
like image 44
user845279 Avatar answered Oct 17 '22 18:10

user845279