简体   繁体   中英

Invoking parameterized/default constructor of a class?

I have a class with two constructors.

Class Sample{

  private ClassOne classOne;
  private ClassTwo classTwo;
  private ClassThree classThree;


  public Sample(){
    classOne = new ClassOne();
    classTwo = new ClassTwo();
    classThree = new ClassThree();
  }

  public Sample(int id){

    classOne = new ClassOne(id);
    classTwo = new ClassTwo(id);
    classThree = new ClassThree(id);

  }

  //some code here
}

have a class Sample with two constructors. Need to instantiate three more classes in Sample class as mentioned(ClassOne, ClassTwo and ClassThree). All three classes contains default and parameterized constructors. If Sample class's default constructor is invoked then ClassOne, ClassTwo and ClassThree 's default cosntructor should get invoked. If Samples parameterized constructor is invoked then ClassOne,ClassTwo and ClassThree 's parameterized constructor is invoked.

I wrote above the code. is there any elegant way to do that?

Assuming you have no other use for id inside your Sample class you could use the factory method pattern:

class Sample {
    private ClassOne classOne;
    private ClassTwo classTwo;
    private ClassThree classThree;

    Sample(ClassOne classOne, ClassTwo classTwo, ClassThree classThree) {
        this.classOne = classOne;
        this.classTwo = classTwo;
        this.classThree = classThree;
    }

    public static Sample factory(int id) {
        ClassOne classOne = null;
        ClassTwo classTwo = null;
        ClassThree classThree = null;
        if ( id == -1 ) {
            classOne = new ClassOne();
            classTwo = new ClassTwo();
            classThree = new ClassThree();
        }
        else {
            classOne = new ClassOne(id);
            classTwo = new ClassTwo(id);
            classThree = new ClassThree(id);
        }
        return new Sample(classOne, classTwo, classThree);
    }
}

Your specific example is probably cleaner in its original formulation, but this is a good way to move complex construction logic out of constructors.

You might change your Sample constructor to accept an Integer object argument. Then the default constructor for Sample could just invoke the Integer construct passing null. You could take it a step further and change the constructors of ClassOne, ClassTwo, and ClassThree to also accept an Integer object argument and handle the null case elegantly:

class Sample {
  private ClassOne classOne;
  private ClassTwo classTwo;
  private ClassThree classThree;

  public Sample(){
    this(null);
  }

  public Sample(Integer id){
    super();
    classOne = new ClassOne(id);
    classTwo = new ClassTwo(id);
    classThree = new ClassThree(id);
  }
  ...
}

class ClassOne {
  private int id;

  public ClassOne(Integer id) {
    super();
    if (id == null) {
      this.id = 0; // or whatever default value
    } else {
      this.id = id.intValue();
    }
  }
  ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM