A Class Is a Blueprint
Up to now your code has lived in methods that pass plain values around. A class lets you bundle related data and the behavior that operates on it into a single named type. The class is the blueprint; the actual things you work with are objects created from it.
A class declares two kinds of members: fields (the data each object holds) and methods (what each object can do).
new Dog() builds an object in memory and hands you a reference to it. d.name and d.bark() reach into that specific object.
Each Object Has Its Own State
The whole point of a class is that you can stamp out many independent objects, each carrying its own field values. Changing one never touches another.
rex and bella are two separate objects. Each has its own name, so each bark() prints a different value. This per-object data is called instance state.
Fields and Methods Work Together
Methods inside a class can read and update that object's own fields directly - no need to pass them in as parameters. The method already "lives on" the object whose data it touches.
Notice increment() takes no arguments. It works on the field belonging to whichever Counter you called it on. This is the difference between a class method and a free-floating static method: the method has an implicit object to act upon.
The this Keyword
Inside a method, this is a reference to the object the method was called on. You usually do not need it - writing count already means this.count. But this becomes essential when a parameter name collides with a field name, which happens constantly in setters and constructors.
A common beginner mistake is writing x = x; inside move. That just assigns the parameter to itself and leaves the field untouched - the compiler will not warn you, and your object silently keeps its old values. this.x = x; is what actually updates the field.
Default Field Values and null References
When you create an object, its fields are not left as garbage - Java initializes them to defaults: 0 for numbers, false for boolean, and null for object references like String. That null default is the source of a classic crash.
u.name is null because nobody set it, so calling .length() on it throws a NullPointerException. Always assign meaningful values to an object before using its fields - which is exactly the problem constructors solve.
Organizing Code Around Classes
Real programs model their domain as classes that hold data and the operations on it together. Here a single BankAccount class keeps a balance and guards how it changes:
The data (balance) and the rules for changing it (deposit, withdraw) live in one place. Code elsewhere asks the account to do things rather than poking at its numbers directly - the foundation of clean, maintainable design.
Next: Constructors
Setting every field by hand after new is tedious and easy to forget - and as you just saw, a forgotten field leaves a null waiting to crash. A constructor lets you require and initialize an object's fields the moment it is created, so a BankAccount can never exist without an owner. That is the next page.
Frequently Asked Questions
What is a class in Java?
A class is a blueprint that defines the data (fields) and behavior (methods) a kind of object will have. The class itself is just the template - you create actual objects from it with new. For example, a Dog class describes that every dog has a name and can bark(), while each new Dog() is a separate dog with its own name.
What is the difference between a class and an object in Java?
A class is the definition; an object is a concrete instance built from that definition with new. One Person class can produce many Person objects, each holding its own field values. Think of the class as the cookie cutter and objects as the individual cookies - changing one object's fields never affects another's.
What does the this keyword do in a Java class?
this refers to the current object - the specific instance whose method is running. You use it to reach an object's own fields, especially when a parameter has the same name as a field (this.name = name;). Without this, the assignment would just set the parameter to itself and the field would stay unchanged.