Setters and Getters#
Usually it is preferred that the data fields of a class are private
(or at least protected
), so that whoever is using your data types does not inadvertently mess them up. The more we can protect the user (programmer), the better. Consider the example of making a Square
. If the data fields, length
and width
, were public
then someone could do the following in their program:
Square x = new Square(10);
x.length = 4;
The user (programmer) has just made a “square” with dimensions 10 X 4. Clearly, this is not a square. By making the length
and width
fields private
, direct access to the instance variables is prohibited, except when coding inside of the class itself. The protected
access modifier is similar to private
but gives access to any file in your current package. If you are building with inheritance, protected
fields will give access within classes that are lower in the hierarchy. (protected
also gives access in places where an object is made, for example, in main
but this is normally not code that would be packaged along with your formal class libraries.)
Setters#
If we wanted to allow the size of a square to be able to change, even with private
data, we could write a setter method. A setter is a public
method, written in the class, that would change data fields, in this case, both length
and width
. Here is an example of a setter for squares:
public void setLength(double newLength){
length = newLength;
width = newLength;
}
Notice how our setter ensures that both the length
and width
data fields stay matched. The user of our Square
data type could now do:
Square x = new Square(10);
x.setLength(4);
}
The essence of a square is preserved while the user is able to change the size (from 10 X 10 to 4 X 4). Note that if we want to be able to change the length of a rectangle, we would need to write another setLength
method, but this one for rectangles. We would need to keep both setLength
methods because we need different things to be done at different levels of the hierarchy. This works since Java will always look first at the level of an object and only move up the hierarchy if the item is not yet found. In the case of the setLength
example, if the object is a Rectangle, then the code from the Rectangle file is used; if the object is a Square, then the code from the Square file is used.
Signature#
A signature is the function name, along with the data types of the parameters. For example, the signature of setLength above is
setLength(double)
When we have methods with the same signature in two different classes connected via the hierarchy, we should use the @override
annotation to make it clear that we understand that this is happening. For example, in the Square
class, we would write
@override
public void setLength(double newLength){
length = newLength;
width = newLength;
}
Our Rectangle
class setLength
method would not have @override
added, since that is the first place we define setLength
in our hierarchy.
Getters#
When we have private
data fields, but we want to give access to the values, we write public
accessor methods, called getters. Here are two such methods for getting the length and width of a rectangle (including of a square, by inheritance):
public double getLength(){
return length;
}
public double getWidth(){
return width;
}
Our code has now developed to this point (note that method headers should be written but are omitted here to save space):
Practice Questions#
Write a setter for the
width
of rectangles.Write a setter for the
width
of squares.