Pax Vobiscum
Pax Vobiscum

Reputation: 2649

Constructor calling constructor with arguments

I need to have a class with two constructors, one with and one without arguments. The one without is supposed to call the other with Randomized arguments, so not default ones.

Here is some sample code:

public Human(int ageIn, String nameIn){
    this.name = nameIn;
    this.age = ageIn;
}

public Human(){
    String[] names = {"Peter", "Olof", "Alva", "Sanna", "Carl", "Illona"};
    double random = Math.random();
    int nameIndex = (int)(names.length*random+0.5);
    String name = names[nameIndex];

    random = Math.random();
    int age = (int)(100*random+0.5);

    this(age, name);
}

The thing that makes this hard is that this() has to be in the beginning of a constructor, but I have to define and figure out name and age before I can call the first constructor with them.

Is there any way around this?

Upvotes: 0

Views: 167

Answers (4)

Spotted
Spotted

Reputation: 4091

Don't mix concerns. A Human should not care about choosing a random name based on a predefined set of names nor compute a random age !

I would rather delete the no-arg constructor (except if you have one defined value for a name and for an age, but it seems that it's not your case) and extract this logic outside of Human, typically in a HumanFactory.

Upvotes: 0

rorschach
rorschach

Reputation: 2947

How about something like this?

public class Human {

    public Human() {
        this(null, -1);
    }

    public Human(String name, int age) {
        if(name == null) {
            name = //your random name generation code
        }

        if(age == -1) {
            age = //your random age generation code
        }

        this.name = name;
        this.age = age;
    }
}

Upvotes: 0

Markus Mitterauer
Markus Mitterauer

Reputation: 1610

Alternatively you could create a factory method to create a 'random' Human:

public class MyProgram {

    public static void main(String[] args) {

        Human someRandomStranger = Human.createRandomHuman();
        //...
    }

}

public class Human {

    public Human(int ageIn, String nameIn){
        this.name = nameIn;
        this.age = ageIn;
    }

    // ...

    public static Human createRandomHuman(){
        String[] names = {"Peter", "Olof", "Alva", "Sanna", "Carl", "Illona"};
        double random = Math.random();
        int nameIndex = (int)(names.length*random+0.5);
        String name = names[nameIndex];

        random = Math.random();
        int age = (int)(100*random+0.5);

        return new Human(age, name);
    }

}

This would keep your constructors clear from stuff that shouldn't be there in the first place. A default constructor that randomly assigns values to it's fields might be accidentially called in your code and create unwanted results.

A properly named factory method on the other hand would help prevent such mistakes and clearly communicate your intention.

Upvotes: 0

Jeroen van Dijk-Jun
Jeroen van Dijk-Jun

Reputation: 1038

You can make static methods which make these random values. Then on line 1 of your constructor you can call:

public Human(){
    this(getRandomAge(), getRandomName());
}

Upvotes: 2

Related Questions