Every exercise so far has been a single method working on values like Integer and String. Real programs model things: an order, a support ticket, a bank account. A class lets you describe a new kind of thing once, and an object is one real thing built from that description.
A class groups related data, called fields, with the code that works on that data, called methods:
public class Dog {
public String name;
public Integer age;
public String describe() {
return name + ' is ' + age + ' years old';
}
}
Notice that describe() has no static keyword. It is an instance method, so it runs on one particular object and can read the fields of that object directly by name.
In a Salesforce org each class usually lives in its own file. In the exercises, you write the class right in the editor.
The class itself holds no data. You create an object from it with the new keyword, then use a dot to reach its fields and methods:
Dog rex = new Dog(); rex.name = 'Rex'; rex.age = 3; System.debug(rex.describe()); // Rex is 3 years old
The class you define becomes a brand new type, so the variable is declared as Dog rex, just like Integer count.
Every object gets its own copy of the fields. Changing one object never changes another:
Dog luna = new Dog(); luna.name = 'Luna'; luna.age = 5; rex.age = 4; System.debug(luna.age); // still 5
Methods can change fields too. A method like public void haveBirthday() { age = age + 1; } updates only the object you call it on.
A field you never set starts out as null, even an Integer. Calling haveBirthday() on a new Dog whose age was never set throws a null pointer exception, so give a field a value before you do math with it.
Almost all Salesforce code is organized into classes. Triggers hand their work to handler classes, and service classes group the logic for one job. Knowing how to define a class and create objects from it is the foundation for everything else in object-oriented Apex.