Learning goals
Model real-world entities with classes and objects, distinguish fields from local variables, use references correctly, and apply basic object lifecycle intuition before constructors and encapsulation.
Class and object
A class is a blueprint; an object is a runtime instance.
public class BankAccount {
String owner; // field (instance variable)
double balance;
void deposit(double amount) {
balance += amount;
}
void printSummary() {
System.out.println(owner + ": $" + balance);
}
}
BankAccount acct = new BankAccount(); // construction
acct.owner = "Ada";
acct.deposit(100);
acct.printSummary();
new allocates memory and runs the constructor (default if you define none).
Fields vs local variables
public class Demo {
int count; // field, default 0
void run() {
int count = 5; // local, shadows field
System.out.println(count); // 5
System.out.println(this.count); // field if set
}
}
Fields live for the object’s lifetime; locals exist only inside the block.
Reference semantics
BankAccount a = new BankAccount();
BankAccount b = a;
b.deposit(50);
System.out.println(a.balance); // same object → 50
a and b reference the same instance. null means no instance:
BankAccount c = null;
// c.deposit(1); // NullPointerException
Always null-check external references when failure is possible.
Static vs instance (preview)
public class Counter {
static int globalCount = 0;
int instanceId;
Counter() {
globalCount++;
instanceId = globalCount;
}
}
Static members belong to the class (one copy). Instance members belong to each object. Use static for utilities and shared constants sparingly.
Object lifecycle (high level)
- Construction —
new, constructor runs. - Use — methods read/write fields.
- Unreachable — no references from GC roots.
- Collected — GC frees memory (timing nondeterministic).
You rarely call System.gc() in application code.
Composition over ad-hoc fields
Model relationships by containing other objects:
public class Address {
String city;
String zip;
}
public class Customer {
String name;
Address shippingAddress;
}
Prefer composition when “has-a” fits better than “is-a” (inheritance comes later).
Records as lightweight classes (JDK 16+)
When data carrier with no mutable identity:
record Product(String sku, String name, double price) {}
Immutability by default—good for DTOs and value objects.
Naming and cohesion
- One class should have a clear responsibility (Single Responsibility Principle).
- Group behavior with the data it operates on (
depositonBankAccount, not scattered static helpers). - Avoid god classes that know everything.
Common mistakes
- Forgetting
new—BankAccount a; a.deposit(1);compile error (uninitialized). - Comparing objects with
==when meaning value equality. - Public mutable fields — leads to uncontrolled state (fix in encapsulation chapter).
- Creating many short-lived objects in hot paths without need—GC pressure (optimize when measured).
- Null as valid “empty” object — prefer empty collections or
Optionalwhere appropriate.
Practice checkpoint
-
Draw mentally: after
Point p1 = new Point(); Point p2 = p1; p2.x = 3, what isp1.x?- Answer:
3(shared reference).
- Answer:
-
Define class
Bookwithtitle,author, methoddescribe()returning"title by author".- Answer: Fields +
return title + " by " + author;
- Answer: Fields +
-
What does
newdo in two words?- Answer: Allocates instance, invokes constructor.
-
When use a
recordinstead of a class?- Answer: Immutable data bundle with generated equals/hashCode/toString.
Interview angles
- “Class vs object?” — Class is template; object is instance in memory.
- “Stack vs heap for objects?” — Object on heap; reference variable in thread stack frame.
- “Why OOP?” — Encapsulation, abstraction, reuse via inheritance/composition—not magic, but structure for large codebases.