Concepts / Defining Classes and Instance Methods

Defining Classes and Instance Methods

A public variable gives direct access, but a getter and setter pair gives the class a place to run code when the value is read or written.

  • Programming

Why Direct Access Looks Good Enough

Suppose one class needs to read a value from another class and also change it. The quickest path seems to be declaring the variable public. Then any class can see it and assign to it directly, and there appears to be no need for extra methods. This is a common first reaction to getter and setter methods: they seem unnecessary. This section examines that belief, shows where it breaks down, and explains what getter and setter methods offer in return.

A useful way to think about the question is this. It is very common to provide both a getter and a setter for a private member variable, and that pairing lets other classes both read and change the value. So the real question is not whether other classes can see and change the value. The real question is what else the class can do when they do.

What a Public Variable Cannot Do

A public variable is accessed directly. There is no method in between, so there is no place for the class to run any code at the moment the value is read or written. Whatever the class wants to know about its own data, it cannot learn from a direct access, because nothing in the class is involved in that access at all.

A getter and setter pair changes this picture. Each read goes through the getter method, and each write goes through the setter method. Because those methods are code that the class controls, the class gets a point where it can respond to every access. The source states the key idea directly: getters and setters are not restricted to reading and writing a value. They can take any action at all.

Tracing a Getter That Counts Reads

The source's example is a getter that keeps track of how many times the variable has been accessed. The following class is an original illustration built on that idea. It stores a temperature in a private variable and keeps a private counter of how many times the getter has been called. Read it carefully, because the goal is to follow the state of the counter as calls happen.

java
Notes on the code
  • temperature and readCount are private, so only code inside Thermometer can touch them directly
  • getTemperature increments readCount before it returns the stored temperature
  • setTemperature is the public write path for temperature

Before you look at the sequence below, predict what happens to the counter. The class starts with readCount at 0. Another class calls getTemperature() twice. What is readCount afterward, and what is the caller's code that makes the calls? Think about it before you check the answer.

What do you think happens?

After two calls to getTemperature() on a new Thermometer, what is readCount?

Reveal answer
Answer:

readCount is 2.

Each call to getTemperature() runs readCount++ once before returning, so two calls increment the counter twice. The calling code never mentions readCount; the increment happens inside the method.

Calling codegetTemperature()readCountprivate inttemperatureprivate double1. call getTemperature()2. readCount++3. read temperature4. return value
When calling code reads the temperature, the steps run in order: the getter is entered, the counter is incremented, the private temperature is read, and the value is returned to the caller.

The diagram shows the order of the steps. The caller enters the getter, the getter updates the counter, the getter reads the private temperature, and the value goes back to the caller. The caller never touches readCount. If temperature had been public, the caller could have read it directly, and the Thermometer class would have no record of that access. The getter is the only place where the class can respond to the access.

Before
readCount = 0   // new Thermometer, no calls yet

readCount is 0

After
readCount = 1   // after one call to getTemperature()

readCount is 1 after the first getTemperature() call

readCount0readCount1one call to getTemperature()
One call to getTemperature() changes readCount from 0 to 1. The returned temperature is unaffected by the counting. Each further call adds one more to the counter.
Worked example

Tracking three reads of the same temperature

A Thermometer is created with temperature set to 21.5 and readCount at 0. Calling code then calls getTemperature() three times in a row. What does each call return, and what is readCount after the third call?

  1. 1
    Set up the starting state

    setTemperature(21.5) stores 21.5 in temperature. readCount is still 0 because no getter has run.

  2. 2
    First call

    readCount++ makes readCount 1. The method returns temperature, which is 21.5.

  3. 3
    Second call

    readCount++ makes readCount 2. The method returns 21.5 again, since nothing changed temperature.

  4. 4
    Third call

    readCount++ makes readCount 3. The method returns 21.5 once more.

Result

Each call returns 21.5, and readCount is 3 after the third call. The returned value and the counter are independent: the getter returns the stored value and also records the access.

Keeping the Public Interface Stable

The second major benefit concerns change over time. A class's public interface is the set of members that other classes are allowed to use. The source states that the private member variable is not part of that interface. Only the public getter and setter methods are. Because of this, the implementation behind those methods can change without changing the interface that other code depends on.

Calling code reaches the private variable only through the two public methods, and those methods form the boundary. If the internal storage or the logic inside a method is changed later, the calling code keeps working, because it never depended on the private variable itself. What stays fixed for callers is the property name and the getter and setter signatures. What may change is how the value is stored and computed inside the class.

The source also describes the cost of skipping this step. If a class was first written with a public variable and later needs a getter and setter, every class that uses that variable must be found and updated. Using the methods from the start avoids that work. The source makes this point even when no extra chores for the methods are yet visible, because the design may change later.

FeaturePublic variableGetter and setter pair
How callers access the valueRead and written directlyRead through getX() and written through setX()
Place to run code on accessNone, because no method is involvedInside the getter or setter, which can run any action
Record of accessesThe class has no record of direct readsThe getter can count accesses, as in the Thermometer example
Effect of changing internal storageEvery class that used the variable may need updatingCallers keep working as long as the method signatures stay the same
Member variable in the public interfaceThe variable itself is publicThe variable stays private and is not part of the public interface

Public variable versus getter and setter pair

Methods That Define a Property Without a Variable

So far the methods have been tied to a variable. The source points out that this link is not required. You can define getter and setter methods even when there is no variable at all. A getter or setter defines a property of the class, and that property may or may not correspond to a member variable. The property is defined by the method signatures, not by storage.

The naming convention determines the property name. For a property named value, the setter is written as setValue, with the word set followed by the property name with its first letter capitalized. A getter for the same property is getValue. The source's own example uses a public void instance method with the signature setValue(double), which gives the class a property named value of type double whether or not a member variable named value exists. The name of the property comes from the method, not from the variable.

java
Notes on the code
  • There is no member variable at all in this class
  • getGreeting defines a property named greeting from its name alone
  • A caller reads the property by calling getGreeting(), and the value comes from the method body each time

In this class, the value is produced fresh each time the property is read. Nothing is stored between reads. Compare this with the Thermometer, where the getter returns a stored field. The two classes present the same kind of property to callers, but the source of the value differs: one reads storage, and the other computes or returns a value from the method body.

Mistakes Beginners Make

  • Common mistake

    Making the variable public because it seems faster to write

    Why it fails

    A public variable removes the only place where the class can run code when the value is read or written, so later changes may require updating every caller.

    Do this instead

    Keep the variable private and expose it through a getter and setter from the start.

  • Common mistake

    Assuming a getter must always return a stored variable

    Why it fails

    The getter is ordinary method code, and the source says a property can exist even when no member variable exists.

    Do this instead

    Let the getter return a stored field, perform an extra action such as counting, or return a value computed in its body.

  • Common mistake

    Giving the method a name that ignores the convention

    Why it fails

    The source recommends following the naming convention carefully because some advanced aspects of Java rely on it.

    Do this instead

    Use set followed by the property name with a capital first letter, and get followed by the same name for the getter.

  • Common mistake

    Expecting callers to know about the counter

    Why it fails

    Callers in the Thermometer example never mention readCount. The counting is a private detail inside the method.

    Do this instead

    Keep the counter private, and let the getter handle the bookkeeping as part of its job.

Practice: Add a Read Counter

MEDIUM

Start from the Thermometer class. Add a private int field named readCount if it is not already there, and make getTemperature increment it before returning the temperature. Then describe, in one or two sentences, what changes for calling code. Does the calling code need to be modified, and why or why not?

Hints
  • The increment belongs inside getTemperature, before the return statement.
  • Think about whether the caller can see readCount, and whether it has to.
  • Compare the caller's code before and after the change.

Summary of Getters, Setters, and Properties

  1. 1
    A public variable gives direct access but no place for the class to run code when the value is read or written.
  2. 2
    A getter and setter pair routes every read and write through methods that the class controls, so the class can take any action, such as counting accesses.
  3. 3
    The private variable is not part of the public interface, so the implementation can change without affecting classes that use the class.
  4. 4
    A getter or setter defines a property even when no member variable exists, and the property name comes from the method name following the Java naming convention.

At a glance

  • A public variable gives direct access, but a getter and setter pair gives the class a place to run code when the value is read or written.
  • A getter can perform extra actions, such as counting how many times a variable has been accessed.
  • Keeping the variable private and exposing getters and setters lets the implementation change without breaking callers.
  • A property is defined by its getter and setter method signatures, so a property can exist even without a matching member variable.