Last modified: January 09, 2024
In CodeHS, when you wanted to get the color of a Rectangle named rect, you would write rect.getColor()
. If you wanted to set the color to red, you would write rect.setColor(Color.RED)
. The getColor()
function is an example of a getter because it is a function that returns the value of a property. The setColor(color)
function is an example of a setter because it sets the value of a property.
In Java, it is good practice to define public getters for fields that are meant to be read from other classes (read access) and setters for fields that other classes are supposed to be able to change (write access). In lesson 3, we will learn about access modifiers that can further control access to fields and other parts of a class, giving a class even more exclusive control of its data. For now, we will just discuss the private access modifier, which makes a field inaccessible from outside the declaring class. By being able to restrict direct access to data, a programmer can then give limited access to the data through the use of getters and setters. Not only does this protect the data from being corrupted from misuse, but it also allows a programmer to define limits on the values a field can have and can allow relationships between different parts of the class to be defined. For example, if the only way to change the width of a rectangle is through the setter, the setter method can contain logic that restricts the value of the width to only positive values. There could even be code that automatically updates the graphical representation of the rectangle every time the width changes. A Rectangle class could even maintain a list of other objects that are interested in the width of that rectangle and every time the width changes, the setter could call a method on those other objects so they can respond to the change. This opens up the door to very powerful features which would be broken if a programmer using the Rectangle class could just directly change the width by writing rect.width = 100
.
Here is an example of a simple Rectangle class that utilizes getters and setters.
public class Rectangle {
// private instance variables that store
// the width and height of the rectangle
private int width;
private int height;
//A default constructor
public Rectangle() {
width = 1;
height = 1;
}
// A getter for width. Returns the value of width.
public int getWidth() {
return width;
}
// A setter for width. Sets the value of width.
// Limits the value of width to positive values.
public void setWidth(int w) {
if (w > 0) {
width = w;
}
}
// A getter for height. Returns the value of height.
public int getHeight() {
return height;
}
// A setter for height. Sets the value of height.
// Limits the value of height to positive values.
public void setHeight(int h) {
if (h > 0) {
height = h;
}
}
// a combined setter for width and height
// sometimes setters will set two values at once
public void setSize(int w, int h) {
setWidth(w);
setHeight(h);
}
}
Note that the logic in setWidth(int w)
and setHeight(int h)
ignores requests to change the height or width to a non-positive integer. Eventually you will learn how to throw exceptions when invalid values are passed into a method, but for now we will just make the method silently ignore invalid requests.
In the setSize(int w, int h)
method, we could have copied the logic from the setWidth(int w)
and setHeight(int h)
methods, but that would be bad practice because it could lead to inconsistent behavior. By calling the setWidth(int w)
and setHeight(int h)
methods from inside the setSize(int w, int h)
method, we guarantee consistent behavior across all the methods that change the height and width. Normally, when you call the setWidth(int w)
method, you would have to call it on an object like this: rect.setWidth(5)
. But which Rectangle would we call setWidth on? Can we call it on the same Rectangle setSize was called on? To access the object a method was called on from within that method, you can use the this keyword. So you could write this.setWidth(w)
to call setWidth on the same rectangle setSize was called on. However, it is allowed to omit the size
in front of the method call because when you call a method without specifying the object it is called on, then the method is called on this
. Thus, setWidth(w)
is equivalent to this.setWidth(w)
.