HI peeps,
I have a question about the following program:

TempScale.java:

public enum TempScale {
    CELSIUS, FAHRENHEIT, KELVIN, RANKINE,
    NEWTON, DELISLE, R�AUMUR, R�MER, LEIDEN 
};    

Temperature.java

public class Temperature {
    private double number;

    private TempScale scale;

    public Temperature() {
        number = 0.0;
        scale = TempScale.FAHRENHEIT;
    }

    public Temperature(double number) {
        this.number = number;
        scale = TempScale.FAHRENHEIT;
    }

    public Temperature(TempScale scale) {
        number = 0.0;
        this.scale = scale;
    }

    public Temperature(double number, TempScale scale) {
        this.number = number;
        this.scale = scale;
    }

    public void setNumber(double number) {
        this.number = number;
    }

    public double getNumber() {
        return number;
    }

    public void setScale(TempScale scale) {
        this.scale = scale;
    }

    public TempScale getScale() {
        return scale;
    }
}

UseTemperature.java

import static java.lang.System.out;

class UseTemperature {

   public static void main(String args[]) {
       final String format = "%5.2f degrees %s\n";

       Temperature temp = new Temperature();
       temp.setNumber(70.0);
       temp.setScale(TempScale.FAHRENHEIT);
       out.printf(format, temp.getNumber(), 
                          temp.getScale());

       temp = new Temperature(32.0);
       out.printf(format, temp.getNumber(), 
                          temp.getScale());

       temp = new Temperature(TempScale.CELSIUS);
       out.printf(format, temp.getNumber(), 
                          temp.getScale());

       temp = new Temperature(2.73, TempScale.KELVIN);
       out.printf(format, temp.getNumber(), 
                          temp.getScale());
   }
}

Now, the way the program works is fairly clear, but what I don't understand is why they use constructors...what's the point of that? My understanding is that everytime a new object is called, then the "equivalent" constructor is called and the values assigned to the variables: like when this statement executes Temperature temp = new Temperature(); then this constructor gets called

public Temperature(){
        number = 0.0;
        scale = TempScale.FAHRENHEIT;
    }

So as mentioned, what's the point of calling the constructor? The variables values can be set using the setters, so what happens if we get rid of them? Can anybody kindly (and clearly) explain the point of having them please?
thanks

Hello 'Violet_82', we can sometimes get rid of the constructor, the example you looked at may not be the best to judge if constructors are important or not. Look at this example, it may makes more sense:

Person.java

public class Person{
    private firstName;
    private lastName;
    private age;

    Person(String firstName,String lastName,int age){
        this.firstName = firstName; //this. is used to point to the variable defined at the top and not the parameter of the constructor
        this.lastName = lastName;
        this.age = age;
    }

    public void setFirstName(String firstName){
        this.firstName = firstName;
    }

    ....
    ....
    ....
}

Here's now how we use this:

Person aBoy = new Person("Hello","World",19);

isn't it more practicle that each time calling the setters ?
NB: the code is not tested, but hope you got the idea ... Good Luck

It's generally classed as good or maintainable programming to initialise all global variables in the constructor rather than wait for them to be set using setters.

thanks for the post.
Sorry if I will say something obvious, but being a beginner I still have quite a lot to learn. Now, in your post amirbwb I guess it makes sense to have a constructor Person(String firstName,String lastName,int age){ rather than a setter public void setFirstName(String firstName). From your code I seem to understand that the purpose of a constructor is only to initialize variables, nothing else. So the advantage of using a constructor over a setter is that a constructor can initialize more than a variable, which is what a setter does?

It's generally classed as good or maintainable programming to initialise all global variables in the constructor rather than wait for them to be set using setters.

I thought the point of a setter was to initialize variables...

There is an overlap in function between constructors and setters, and no rigid rules about which to use. But some typical guidlines include:

  • If a variable must be set for an instance to be valid (eg Person must have a name and social security number) then set them in the constructor. That way there's no risk of an invalid instance because someone forgot to set something.
  • If it's optional to set a variable then an ordinary setter is better.
  • If a value can change you must have a setter, even if it is also set in the constructor.

Don't forget also that you can have multiple constructors, each taking a different number of parameters, so you can use which ever constructor lets you set exactly those values that you know when creating the new instance.

In the end this is mostly a question of style and preference, so I wouldn't get too hung up on it.

I thought the point of a setter was to initialize variables...

A common mistake as the name setter would suggest that you use it for that purpose. But I'm 100% certain that you initialise global variables in the constructor (even if you initialise them as null, its just good programming practice), then use the setters to modify them later in the program.

Hi RockJake - eould you like to define "global variables" for those of us who speak Java? ;)
How about initialisation in their declaration, or in an instance initialiser block? Both those lead to simpler safer code when there are multiple contructors.

Edited 3 Years Ago by JamesCherrill

that's fine thanks, I guess I will learn with practice. Also, what confused me a bit about the above program was the fact that the setters are there but are not used, but we've discussed a similar issue in a previous post (the setters are just there as an example)

Global variables are ones that can be used by all of the private, protected or public methods in the class. As opposed to local variables which can only be used inside the method that they are declared in.

Yes, I guesed that was what you meant, although when people do say "global" they usually mean "public" But because most of the people reading these posts are early on the Java learning curve you should stick to standard Java terminology. There's no such thing as "global" in the Java language. (In fact there's only one use of the phrase "global variable" in the whole Language Spec, and that's an informal use in a discussion of memory models for multi-threading in the VM.)
It's just a matter of avoiding confusion for readers who may be already pretty confused about Java ;)

Edited 3 Years Ago by JamesCherrill

Understood. However I completely disagree with the use of public variables.
They should be private and have methods that access them...encapsulate, encapsulate, encapsulate!

I completely disagree with the use of public variables. They should be private and have methods that access them.

I agree absolutely (with the exception of static final public, of course)

So the advantage of using a constructor over a setter is that a constructor can initialize more than a variable, which is what a setter does?

Yes you can say that :)
I'am sure that you will learn with time the hidden advantages of constructors,
good luck

So the advantage of using a constructor over a setter is that a constructor can initialize more than a variable, which is what a setter does?

Not really, the main advantage of using a constructor to initialize all member fields is to ensure one-shot initialization of objects which when coupled with the use of final fields, is a good thing when writing multi-threaded code. If you use setters to initialize your object, there exists a point wherein you have an incomplete instance available which isn't a good thing. As an example:

Person p = new Person();
// some conditional check/logic
p.setName("Sanjay");
p.setAge(42);

The problem with the above code is that you have a possibility of having an "invalid" Person instance in your code; a Person object which doesn't have any fields set.

They should be private and have methods that access them...encapsulate, encapsulate, encapsulate!

Unfortunately, this kind of boilerplate is actually a Java language limitation. In C#, one can freely access public fields and if abstraction/encapsulation is required, they can be converted in "method" calls without changing any client code. Something similar can be done for Python (in which everything is public anyways).

So yes, though it's a good thing to lean towards encapsulation by creating an army of getters and setters (typical Java way of doing pretty much anything), it's worthwhile to note that it really isn't an accepted OO practice but more like a language limitation.

Edited 3 Years Ago by ~s.o.s~

This question has already been answered. Start a new discussion instead.