Book.java: Getters and Setters (a.k.a. Accessors and Mutators)

Getters (a.k.a. Accessors)

Getters, or accessors, are methods that provide access to an object's instance variables. In essence, we are providing a layer of indirection. Simple classes often have getters that return the associated instance variable and nothing more. For example:

public String getTitle()
{
  return title;
}

public String getAuthor()
{
  return author;
}

public int getRating()
{
  return rating;
}
simply return the title, author, and rating instance variables, respectively. Note that the name of the first getter is getTitle. Prefixing the corresponding instance variable with "get" is a common naming convention for getters.

Getter methods shine in complex classes. For example, an object may need to perform network or database I/O to access the requested value. As such, having a getter method abstracts away the details of retrieving the desired value.

Questions

  1. Why do we need getters?
  2. Why are getters useful abstractions?

Setters (a.k.a. Mutators)

Setters, or mutators, are methods that provider the caller with an opportunity to update the value of a particular instance variable. Similar to getters, setters are often named by prefixing the corresponding instance variable with "set". For example:

public void setTitle(String title)
{
  this.title = title;
}

public void setAuthor(String author)
{
  this.author = author;
}

public void setRating(int rating)
{
  this.rating = rating;
}
Note that, unlikely getters, setters have no return value. A setter's job is usually limited to changing the value of an instance variable. Like getters, setters provide a useful layer of indirection to manipulating instance variables. Suppose we want our Book class to only using rating values between 0 and 5. The setter provides an excellent opportunity for enforcing these constraints:

public void setRating(int rating)
{
    if (rating > 5) {
        this.rating = 5;
    } else if (rating < 0) {
        this.rating = 0;
    } else {
        this.rating = rating;
    }
}
This improved setRating setter can also be used by Book's constructor to ensure that we only initialize objects with valid ratings:

public Book(String title, String author, int rating)
{
    this.title = title;
    this.author = author;
    setRating(rating);
}

Questions

  1. Why do we need getters?
  2. Why are getters useful abstractions?