So far every field has been public, which means any code anywhere can change it to anything. Nothing stops other code from writing thermostat.temperature = 500;. Encapsulation is the habit of hiding the data of an object and only letting the outside world change it through methods that enforce the rules.
Mark the field private so only code inside the class can touch it, then add public methods that are the only way in:
public class Thermostat {
private Integer temperature = 20;
public Integer getTemperature() {
return temperature;
}
public void setTemperature(Integer value) {
if (value >= 10 && value <= 30) {
temperature = value;
}
}
}
Code outside the class reads the temperature through getTemperature(), and the only way to change it is setTemperature(), which ignores anything outside 10 to 30. The object can never hold a bad value.
A method that might refuse a change can return a Boolean so the caller knows what happened:
public Boolean raise(Integer degrees) {
if (temperature + degrees > 30) {
return false;
}
temperature = temperature + degrees;
return true;
}
Apex also has a shorthand for a field with a getter and a setter, called a property:
public Integer temperature { get; private set; }
Any code can read temperature, but only code inside the class can set it.
In a real org, reading a private field from another class is a compile error. The exercise editor runs all of your code together in one block, where Apex is more forgiving about private, so treat the rule as a promise you keep: only the methods of a class should change its private data.
When every change goes through one method, there is exactly one place to check the rules and one place to fix a bug. Salesforce service classes follow this pattern: they keep their working data private and expose a small set of public methods that do the job safely.