Reading — step 1 of 7
Learn
Classes are the heart of Java's object-oriented model. A class bundles fields (data/state) with methods (behavior). An object (or instance) is a specific thing built from the class blueprint. Java's class syntax is more verbose than Python or JavaScript — but every part has a reason.
Defining a class
public class Point {
int x; // field
int y; // field
Point(int x, int y) { // constructor
this.x = x;
this.y = y;
}
double distance(Point other) { // method
int dx = x - other.x;
int dy = y - other.y;
return Math.sqrt(dx * dx + dy * dy);
}
}
Five parts of the anatomy:
public— access modifier (more on these below).class Point— the class declaration. PascalCase by convention.- Fields — variables that belong to each instance.
- Constructor — special method (same name as class, no return type) that runs when you
newan instance. - Methods — operations on the object.
Creating instances with new
Point p = new Point(3, 4);
System.out.println(p.x); // 3
System.out.println(p.distance(new Point(0, 0))); // 5.0
The new keyword:
- Allocates memory for a new Point.
- Calls the constructor.
- Returns a reference to the new object.
this — the current instance
Inside instance methods, this refers to the object the method was called on:
public class Point {
int x, y;
Point(int x, int y) {
this.x = x; // this.x is the field; x is the parameter
this.y = y;
}
}
Without this, x = x would just assign the parameter to itself. You need this.x to disambiguate field from parameter.
When there's no naming clash, this is optional — but many style guides write it explicitly for clarity.
Access modifiers
Control visibility:
public class Point {
public int x; // accessible from anywhere
private int y; // accessible only within Point
protected int z; // accessible within package + subclasses
int w; // package-private (default — no modifier)
}
Convention: fields private, methods public (or whatever access they need). Use getter/setter methods to expose data:
public class BankAccount {
private double balance;
public double getBalance() { return balance; }
public void deposit(double amount) {
if (amount > 0) balance += amount;
}
}
This is encapsulation — hide implementation details, expose a controlled interface.
Constructors — overloading
public class Point {
int x, y;
Point() { // no-arg constructor
this(0, 0); // calls the other constructor
}
Point(int x, int y) {
this.x = x;
this.y = y;
}
}
Point origin = new Point(); // (0, 0)
Point p = new Point(3, 4);
Multiple constructors with different parameter lists. this(...) from inside a constructor calls another constructor of the same class.
static — belongs to the class, not an instance
public class Counter {
static int totalCreated = 0; // shared across ALL instances
int id; // per-instance
Counter() {
totalCreated++;
id = totalCreated;
}
}
new Counter(); // totalCreated = 1
new Counter(); // totalCreated = 2
System.out.println(Counter.totalCreated); // 2 — accessed via class name
static members belong to the class, not any specific instance. Static methods can be called via the class: Math.sqrt(2).
record — concise data classes (Java 16+)
record Point(int x, int y) {}
Point p = new Point(3, 4);
System.out.println(p.x()); // 3 — auto-generated accessor
System.out.println(p); // Point[x=3, y=4]
System.out.println(p.equals(new Point(3, 4))); // true
A record auto-generates: constructor, accessors (x(), y()), equals, hashCode, toString. For immutable data carriers, this saves dozens of lines vs a normal class.
toString(), equals(), hashCode()
Every class inherits these from Object. Default implementations are usually wrong:
class Point { int x, y; ... }
Point a = new Point(3, 4);
Point b = new Point(3, 4);
System.out.println(a.equals(b)); // false — default checks reference identity
Override them when needed (or use record, which generates correct versions for free).
Common mistakes
- Forgetting
this.field = fieldin constructors with same-name parameters. - Public fields everywhere — breaks encapsulation. Use private + getters.
- Modifying fields without
this.when there's a parameter shadowing — assigns to itself, not the field. - Comparing objects with
==— checks reference, not value. Overrideequals()(or userecord). - Forgetting to
new—Point p;is anullreference, not a Point.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…