What you'll learn
This is the module where Java clicks. Object-oriented programming (OOP) is how Java models the world: as objects that bundle data and behaviour together. Master it and everything from Android apps to enterprise systems opens up.
By the end you'll be able to:
- Write classes with fields and methods, and create objects with
new - Initialise objects with constructors (including overloaded ones)
- Use
thisto refer to the current object - Protect data with encapsulation, access modifiers, and getters/setters
- Share data and behaviour across all objects with
static - Lock values, methods, and classes with
final
Classes & objects
Procedural code (what you've written so far) is a list of instructions. OOP organises code around objects — self-contained units that hold state (data) and behaviour (methods). A class is the blueprint; an object is a concrete thing built from it.
Class — the blueprint
Dog
Defines what every dog has (name, age) and does (bark).
A class's fields describe what an object has; its methods describe what it does. You bring an object to life with the new keyword:
public class Dog {
String name; // fields = state
int age;
void bark() { // method = behaviour
System.out.println(name + " says Woof!");
}
public static void main(String[] args) {
Dog d = new Dog(); // create an object with 'new'
d.name = "Rex";
d.age = 3;
d.bark();
System.out.println(d.name + " is " + d.age);
}
}Constructors
Setting each field after creation (like d.name = ...) is tedious and error-prone. A constructor is a special method — same name as the class, no return type — that runs the moment you call new, letting you set up the object in one step. If you don't write one, Java gives you a default (no-argument) constructor for free.
public class Dog {
String name;
int age;
Dog(String name, int age) { // constructor: runs on 'new'
this.name = name;
this.age = age;
}
Dog(String name) { // overloaded constructor
this(name, 0); // calls the other one
}
public static void main(String[] args) {
Dog a = new Dog("Rex", 3);
Dog b = new Dog("Pup"); // age defaults to 0
System.out.println(a.name + ", " + a.age);
System.out.println(b.name + ", " + b.age);
}
}Note
this(...) to avoid repeating setup code.The this keyword
Inside a method or constructor, this refers to the current object. Its most common use is disambiguating a field from a parameter with the same name — this.name = name means "set this object's name field to the name parameter." It also lets one constructor call another with this(...).
Encapsulation & access modifiers
Encapsulation means hiding an object's internal data and exposing only a controlled interface. You mark fields private so nothing outside the class can touch them directly, then provide getters and setters to read and change them on your terms — validating input, enforcing rules, keeping the object always valid.
public methods — the controlled interface
private fields — hidden state
balanceThe outside world can only touch balance through your methods — so you control the rules.
public class BankAccount {
private double balance; // hidden from outside
public double getBalance() { // read access
return balance;
}
public void deposit(double amount) { // write access WITH rules
if (amount > 0) {
balance += amount;
}
}
public static void main(String[] args) {
BankAccount acc = new BankAccount();
acc.deposit(100);
acc.deposit(-50); // rejected by validation
System.out.println(acc.getBalance());
}
}Four access modifiers control visibility, from most open to most closed:
public— accessible from anywhereprotected— accessible in the same package and by subclasses- (default / package-private) — accessible only in the same package
private— accessible only inside the same class
Tip
private by default, and expose behaviour through methods. This keeps objects in control of their own state — the heart of good OOP.static fields & methods
A static member belongs to the class itself, not to any single object — so it's shared by every instance. A static field is perfect for a shared counter or a constant; a static method (like Math.max) is called on the class without creating an object.
Instance members
Belong to each object. Every Dog has its own name. Accessed via the object: rex.name.
static members
Belong to the class, shared by all objects. Accessed via the class: Dog.count.
public class Counter {
static int count = 0; // shared by ALL Counters
int id; // unique per object
Counter() {
count++;
id = count;
}
public static void main(String[] args) {
new Counter();
new Counter();
Counter third = new Counter();
System.out.println("I am object #" + third.id);
System.out.println("Total created: " + Counter.count);
}
}Note
main is static for exactly this reason — the JVM can call it without first creating an object. Static initialization blocks (static { ... }) run once when the class first loads, handy for one-time setup.The final keyword
final means "this can't change," and it works on three things:
- final variable — a constant; can be assigned only once
- final method — cannot be overridden by a subclass (Module 9)
- final class — cannot be extended at all (e.g.
Stringis final)
Note
final when they shouldn't change makes your intent clear and prevents accidental modification — a small habit that pays off in large programs.Recap & quick check
Key takeaways
- A class is a blueprint; an object is a concrete instance created with new.
- Fields hold state, methods define behaviour, constructors initialise the object.
- this refers to the current object — great for field/parameter name clashes.
- Encapsulation = private fields + public getters/setters that enforce your rules.
- static members belong to the class and are shared; final locks a value, method, or class.
Quick check
1. What is the relationship between a class and an object?
2. When does a constructor run?
3. Why make fields private and expose getters/setters?
4. A static field is…
5. What does 'final' do to a variable?
Brilliant — you've crossed into object-oriented thinking. Next up: Module 9 — Inheritance & Polymorphism, where classes start building on one another.