Getters, Setters, and Constructors

Private Attributes

In the last example we created a student class which had attributes studentNumber, studentFirstName, and studentLastName. We changed the value of those attributes from the main method by accessing them directly using code "myStudent.studentNumber = 108234234". While this works fine for our simple example, it is bad practice to write code in this way. If we allow programmers to directly modify our attributes, then they could change our attributes to invalid values. For example, in UCC all student numbers are 8 or 9 digit numbers. So if a programmer is allowed to change our studentNumber attribute to a four digit number, then that could cause unexpected errors. Likewise, if we had a class that stored units of time, how could we stop the system allowing a value of 61 for the minutes attribute?

Lets look at the time problem in detail:

Time class:

class CurrentTime{
    int hour;
    int minute;

    void printTime(){

        System.out.println("The time is: " + hour + ":" + minute);
    }

}

Main Class:

class Main{

    public static void main(String args[]){
        CurrentTime theCurrentTime = new CurrentTime();
        theCurrentTime.hour = 12;
        theCurrentTime.minute = 67;

        theCurrentTime.printTime();
    }
}

In the above example, the current time is printed as 12:67 and thats obviously not very good but how do we protect ourselves form that happening? It's actually quite simple, we use an object orientated design principle called Encapsulation to hide the data attributes and prevent incorrect modification. The previous sentence might seem wordy but, in practice, it's actually quite simple. First we declare the class level attributes as private, this stops them from being directly modified. We then create getter and setter methods for each attribute if the attributes need to be modified from an external class. A getter method, will return the current value of an attribute to an external class if called. A setter method will allow an external class to change the value of an attribute. In our time example, we can make sure that our setter method for the minute attribute does not allow minute to be changed to a value greater than 59.

Let's look at this in practice:

class CurrentTime{
    private int hour = 0;
    private int minute = 0;

    //setter method for hour
    public void setHour(int newHourValue){

        //only sets hour if new value is within valid range

        if(newHourValue<24 && newHourValue >= 0){
            hour = newHourValue;
        }
    }

    //setter method for minute
    public void setMinute (int newMinuteValue){

        //only sets minute if new value is within valid range

        if(newMinuteValue<60 && newMinuteValue >= 0){
            minute = newMinuteValue;
        }
    }

    print void printTime(){

        System.out.println("The time is: " + hour + ":" + minute);
    }

}

Main class:

class Main{

    public static void main (String args[]){

        CurrentTime theCurrentTime = new CurrentTime();

        theCurrentTime.setHour(12);
        theCurrentTime.setMinute(12);

        theCurrentTime.printTime();
    }
}

Lets look back at that example, the attributes were declared as private so they could only be accessed and modified from within the CurrentTime class. We then created two public setter methods which would allow the attributes to be changed from outside the class, except, they only accept values within a valid range. We didn't create any getter methods so the only way the CurrentTime can be viewed is by using the printTime() method, just the way we want it.

The anatomy of the getter and setter methods

We've seen an example of a setter method earlier in the CurrentTime class. They usually have an access modifier of public so they can be accessed from external classes. They usually have a return type of void since they don't normally need to return a value. They are usually named as "set" + the name of the attribute they are modifying (starting with a capital letter). Lastly they always have a parameter in the parameter in the brackets. This is a special variable which receives a new value every time the method is called with a matching argument in the brackets. The setter method then takes that new value and assigns it to the attribute.

Lets look closely at a simple setter method:

class SetterExample{
    //Here is our attribute,  a simple string which has the initial value of "Attribute"
    String attribute = "Attribute";

    //now lets declare our setter method!
    //remember the anatomy:
    //accessModifier=public  returnType=void name="set"+attributeName brackets=(Parameter=Variable to receive new value for attribute!)

    public void setAttribute(String newValue){

        //notice we declared a variable called "newValue" inside the brackets!
        //this will receive a String value from the calling statement so we can do something with it
        //look at the value being sent in the brackets of the calling statement in the main method below!

        //now we replace the value of the String "attribute" with the value contained in the String "newValue"

        attribute = newValue;
    }
}

Now for the main class:

public class Main{

    public static void main(String args[]){

        //create a new instance of our setter example class
        SetterExample example = new SetterExample();

        //now we call our setter method - here is the calling statement:

        //note the String in the brackets - this will be sent to the setter method and received in the parameter variable we declared String  "newValue"
        example.setAttribute("The attribute String has now been changed to this sentence!!");
    }
}

We've seen enough of setter methods now so lets move on and have a look at getter methods. A getter method needs to return the value of the attribute to the external calling statement. It does this using a return type and a return statement. When declaring a getter method, the access modifier is usually set to public. The return type is set to the data type of the attribute to be returned. The method is usually named with "get" + plus the name of the attribute and the brackets are usually empty. The method will always contain a return statement.

Lets add a getter method to out previous example:

class GetterAndSetterExample{

    //Here is our attribute,  a simple string which has the initial value of "Attribute"
    String attribute = "Attribute";

    //lets declare our getter method
    //the access modifier should be public
    //the return type should be "String" because we're returning an attribute which is a String
    //it should be named with "get"+the name of the attribute

    public String getAttribute(){
        //now all we need is a return statement which will return the value of the attribte

        return attribute;
    } // now lets look at the main method below and see what happens

    //now lets declare our setter method!
    //remember the anatomy:
    //accessModifier=public  returnType=void name="set"+attributeName brackets=(Parameter=Variable to receive new value for attribute!)

    public void setAttribute(String newValue){

        //notice we declared a variable called "newValue" inside the brackets!
        //this will receive a String value from the calling statement so we can do something with it
        //look at the value being sent in the brackets of the calling statement in the main method below!

        //now we replace the value of the String " attribute" with the value contained in the String "newValue"

        attribute = newValue;
    }
}

Now for the main class:

public class Main{

    public static void main(String args[]){

        //create a new instance of our setter example class
        GetterAndSetterExample example = new GetterAndSetterExample();

        //now we call our setter method - here is the calling statement:

        //note the String in the brackets - this will be sent to the setter method and received in the parameter variable we declared String  "newValue"
        example.setAttribute("The attribute String has now been changed to this sentence!!");

        //lets call our getter method - a String will be returned 
        //we could save the returned String into a String variable but in this case we're going to just print it!

        System.out.println(example.getAttribute());

        //This output will be printed - "The attribute String has now been changed to this sentence!!"
    }
}

The Constructor

The Constructor method is a special method in Java. Its purpose is to create (/construct) an instance of an of an object! If you don't explicitly write a constructor method, a default constructor method is used. The default constructor completes background plumbing which we wont go into detail about (it reserves memory space in ram for example). When you create your own constructor method, you can make it perform a series of steps when creating the object. These steps usually involve assigning values to class level attributes and calling a few methods. Constructors can be really useful and should be used when applicable.

Here is the student class:

public class Student{

    //attribute variables
    int studentNumber = 0;
    string name = "";

    //here is the constructor method
    //it is declared with not return type (notice the lack of the word void!)
    //it is given the same name as the class (Student in this case...)

    public Student(){
        //our constructor is going to call a print method
        printStudentDetails();
    }

    private void printStudentDetails(){
        System.out.println(this.studentNumber + "    " + this.name);
    }
}

Here is the main class, this is where we call the constructor method….

public main{

    public static void main(String args[]){

        Student myNewStident = __new Student()__;

        //notice the new keyword and the "Student()" this is actually calling the constructor we created (or the default one if we didn't create one)
    }
}

Video Tutorial (Getter and Setter)

This video demonstrates a shortcut to generating Getters and Setters in Netbeans!

Video Tutorial (Constructor)