Object-Oriented Basics
The this Keyword
Current Object Reference
Your setter has void setName(String name). Inside, which name is which?
The this keyword refers to the current object, letting you write
this.name = name to distinguish the field from the parameter.
Disambiguate fields from parameters
Use this.field when names conflict.
public class Disambiguate {
public static void main(String[] args) {
System.out.println("=== Disambiguating with 'this' ===\n");
// Without 'this', names would shadow fields
Person person = new Person("Alice", 30);
System.out.println("Name: " + person.getName());
System.out.println("Age: " + person.getAge());
// Update using setters
person.setName("Bob");
person.setAge(25);
System.out.println("\nAfter update:");
System.out.println("Name: " + person.getName());
System.out.println("Age: " + person.getAge());
System.out.println("\n=== Why Same Names? ===");
System.out.println("✓ Clear what the parameter represents");
System.out.println("✓ No need to invent different names");
System.out.println("✓ Common convention in Java");
}
}
class Person {
private String name;
private int age;
// Parameters have same name as fields
Person(String name, int age) {
this.name = name;
this.age = age;
}
// Getter - no disambiguation needed
public String getName() {
return name; // Just 'name' is fine here
}
public int getAge() {
return age;
}
// Setter - needs 'this' to disambiguate
public void setName(String name) {
this.name = name; // this.name = field, name = parameter
}
public void setAge(int age) {
this.age = age;
}
}
public static void main(String[] args)
1public class Disambiguate {2 public static void main(String[] args) {3 System.out.println("=== Disambiguating with 'this' ===\n");4 5 // Without 'this', names would shadow fields //?problem6 Person person = new Person("Alice", 30);7 System.out.println("Name: " + person.getName());output=== Disambiguating with 'this' ===this.name ← Alice, this.age ← 30, person ← ⟨Person A⟩
5 // Without 'this', names would shadow fields //?problem6 Person person→ ⟨Person A⟩ = new Person("Alice", 30);7 System.out.println("Name: " + person.getName());8 System.out.println("Age: " + person.getAge());9 10 // Update using setters11 person.setName("Bob"); //?update12 person.setAge(25);13 System.out.println("\nAfter update:");14 System.out.println("Name: " + person.getName());15 System.out.println("Age: " + person.getAge());16 17 System.out.println("\n=== Why Same Names? ===");18 System.out.println("✓ Clear what the parameter represents");19 System.out.println("✓ No need to invent different names");20 System.out.println("✓ Common convention in Java");21 }22}2324class Person {25 private String name; //?fields26 private int age;27 28 // Parameters have same name as fields //?constructor29 Person(String nameAlice, int age30) {30 this.name→ Alice = nameAlice; //?thisname31 this.age→ 30 = age30;32 }public String getName()
pass 1 of 234// Getter - no disambiguation needed //?getter35public String getName() {36 return nameAlice; // Just 'name' is fine here37}System.out.println("Name: " + person.getName());
6Person person = new Person("Alice", 30);7System.out.println("Name: " + person.getName());8System.out.println("Age: " + person.getAge());outputName: Alicepublic int getAge()
pass 1 of 239public int getAge() {40 return age30;41}System.out.println("Age: " + person.getAge());
7System.out.println("Name: " + person.getName());8System.out.println("Age: " + person.getAge());910// Update using setters11person.setName("Bob"); //?update12person.setAge(25);outputAge: 30this.name ← Bob
10 // Update using setters11 person.setName("Bob"); //?update12 person.setAge(25);13 System.out.println("\nAfter update:");14 System.out.println("Name: " + person.getName());15 System.out.println("Age: " + person.getAge());16 17 System.out.println("\n=== Why Same Names? ===");18 System.out.println("✓ Clear what the parameter represents");19 System.out.println("✓ No need to invent different names");20 System.out.println("✓ Common convention in Java");21 }22}2324class Person {25 private String name; //?fields26 private int age;27 28 // Parameters have same name as fields //?constructor29 Person(String name, int age) {30 this.name = name; //?thisname31 this.age = age;32 }33 34 // Getter - no disambiguation needed //?getter35 public String getName() {36 return name; // Just 'name' is fine here37 }38 39 public int getAge() {40 return age;41 }42 43 // Setter - needs 'this' to disambiguate //?setter44 public void setName(String nameBob) {45 this.name→ Bob = nameBob; // this.name = field, name = parameter46 }this.age ← 25
11 person.setName("Bob"); //?update12 person.setAge(25);13 System.out.println("\nAfter update:");14 System.out.println("Name: " + person.getName());15 System.out.println("Age: " + person.getAge());16 17 System.out.println("\n=== Why Same Names? ===");18 System.out.println("✓ Clear what the parameter represents");19 System.out.println("✓ No need to invent different names");20 System.out.println("✓ Common convention in Java");21 }22}2324class Person {25 private String name; //?fields26 private int age;27 28 // Parameters have same name as fields //?constructor29 Person(String name, int age) {30 this.name = name; //?thisname31 this.age = age;32 }33 34 // Getter - no disambiguation needed //?getter35 public String getName() {36 return name; // Just 'name' is fine here37 }38 39 public int getAge() {40 return age;41 }42 43 // Setter - needs 'this' to disambiguate //?setter44 public void setName(String name) {45 this.name = name; // this.name = field, name = parameter46 }47 48 public void setAge(int age25) {49 this.age→ 25 = age25;50 }output After update:public String getName()
pass 2 of 234// Getter - no disambiguation needed //?getter35public String getName() {36 return nameBob; // Just 'name' is fine here37}System.out.println("Name: " + person.getName());
13System.out.println("\nAfter update:");14System.out.println("Name: " + person.getName());15System.out.println("Age: " + person.getAge());outputName: Bobpublic int getAge()
pass 2 of 239public int getAge() {40 return age25;41}System.out.println("Age: " + person.getAge());
14 System.out.println("Name: " + person.getName());15 System.out.println("Age: " + person.getAge());16 17 System.out.println("\n=== Why Same Names? ===");18 System.out.println("✓ Clear what the parameter represents");19 System.out.println("✓ No need to invent different names");20 System.out.println("✓ Common convention in Java");21}outputAge: 25 === Why Same Names? === ✓ Clear what the parameter represents ✓ No need to invent different names ✓ Common convention in Java
this.name is the field. name alone is the parameter.
Method chaining
Return this to enable fluent interfaces.
public class MethodChaining {
public static void main(String[] args) {
System.out.println("=== Method Chaining ===\n");
int addAmount = 5;
// Traditional way: separate statements
Counter counter1 = new Counter();
counter1.increment();
counter1.increment();
counter1.add(addAmount);
System.out.println("Traditional: " + counter1.getValue());
// Chained way: single statement
Counter counter2 = new Counter();
counter2.increment().increment().add(addAmount);
System.out.println("Chained: " + counter2.getValue());
System.out.println("\n=== String Builder Pattern ===");
// Build message fluently
MessageBuilder builder = new MessageBuilder();
String message = builder
.append("Hello")
.append(", ")
.append("World")
.append("!")
.build();
System.out.println("Message: " + message);
System.out.println("\n=== Benefits ===");
System.out.println("✓ More concise code");
System.out.println("✓ Reads like natural language");
System.out.println("✓ No need for temporary variables");
}
}
class Counter {
private int value = 0;
// Returns 'this' to enable chaining
public Counter increment() {
value++;
return this; // Return the same object!
}
public Counter add(int amount) {
value += amount;
return this; // Return the same object!
}
public Counter reset() {
value = 0;
return this;
}
public int getValue() {
return value;
}
}
class MessageBuilder {
private StringBuilder sb = new StringBuilder();
public MessageBuilder append(String text) {
sb.append(text);
return this; // Enables: append("a").append("b")
}
public MessageBuilder appendLine(String text) {
sb.append(text).append("\n");
return this;
}
public String build() {
return sb.toString();
}
}
public class MethodChaining {
public static void main(String[] args) {
System.out.println("=== Method Chaining ===\n");
int addAmount = 2;
// Traditional way: separate statements
Counter counter1 = new Counter();
counter1.increment();
counter1.increment();
counter1.add(addAmount);
System.out.println("Traditional: " + counter1.getValue());
// Chained way: single statement
Counter counter2 = new Counter();
counter2.increment().increment().add(addAmount);
System.out.println("Chained: " + counter2.getValue());
System.out.println("\n=== String Builder Pattern ===");
// Build message fluently
MessageBuilder builder = new MessageBuilder();
String message = builder
.append("Hello")
.append(", ")
.append("World")
.append("!")
.build();
System.out.println("Message: " + message);
System.out.println("\n=== Benefits ===");
System.out.println("✓ More concise code");
System.out.println("✓ Reads like natural language");
System.out.println("✓ No need for temporary variables");
}
}
class Counter {
private int value = 0;
// Returns 'this' to enable chaining
public Counter increment() {
value++;
return this; // Return the same object!
}
public Counter add(int amount) {
value += amount;
return this; // Return the same object!
}
public Counter reset() {
value = 0;
return this;
}
public int getValue() {
return value;
}
}
class MessageBuilder {
private StringBuilder sb = new StringBuilder();
public MessageBuilder append(String text) {
sb.append(text);
return this; // Enables: append("a").append("b")
}
public MessageBuilder appendLine(String text) {
sb.append(text).append("\n");
return this;
}
public String build() {
return sb.toString();
}
}
public class MethodChaining {
public static void main(String[] args) {
System.out.println("=== Method Chaining ===\n");
int addAmount = 10;
// Traditional way: separate statements
Counter counter1 = new Counter();
counter1.increment();
counter1.increment();
counter1.add(addAmount);
System.out.println("Traditional: " + counter1.getValue());
// Chained way: single statement
Counter counter2 = new Counter();
counter2.increment().increment().add(addAmount);
System.out.println("Chained: " + counter2.getValue());
System.out.println("\n=== String Builder Pattern ===");
// Build message fluently
MessageBuilder builder = new MessageBuilder();
String message = builder
.append("Hello")
.append(", ")
.append("World")
.append("!")
.build();
System.out.println("Message: " + message);
System.out.println("\n=== Benefits ===");
System.out.println("✓ More concise code");
System.out.println("✓ Reads like natural language");
System.out.println("✓ No need for temporary variables");
}
}
class Counter {
private int value = 0;
// Returns 'this' to enable chaining
public Counter increment() {
value++;
return this; // Return the same object!
}
public Counter add(int amount) {
value += amount;
return this; // Return the same object!
}
public Counter reset() {
value = 0;
return this;
}
public int getValue() {
return value;
}
}
class MessageBuilder {
private StringBuilder sb = new StringBuilder();
public MessageBuilder append(String text) {
sb.append(text);
return this; // Enables: append("a").append("b")
}
public MessageBuilder appendLine(String text) {
sb.append(text).append("\n");
return this;
}
public String build() {
return sb.toString();
}
}
addAmount ← 5, counter1 ← ⟨Counter A⟩
1public class MethodChaining {2 public static void main(String[] args) {3 System.out.println("=== Method Chaining ===\n");4 int addAmount→ 5 = 5; //@addAmount=2, 105 6 // Traditional way: separate statements //?traditional7 Counter counter1→ ⟨Counter A⟩ = new Counter();8 counter1.increment();9 counter1.increment();output=== Method Chaining ===value ← 1
pass 1 of 440// Returns 'this' to enable chaining //?returnthis41public Counter increment() {42 value→ 1++;43 return this; // Return the same object!44}All 4 passes — pass 1 is the card above pass amountvalue1 — 0 → 1 2 — 1 → 2 3 — 0 → 1 4 5 1 → 2 counter1.increment();
7Counter counter1 = new Counter();8counter1.increment();9counter1.increment();10counter1.add(addAmount);counter1.add(addAmount);
8counter1.increment();9counter1.increment();10counter1.add(addAmount5);11System.out.println("Traditional: " + counter1.getValue());value ← 7
pass 1 of 246public Counter add(int amount5) {47 value→ 7 += amount5;48 return this; // Return the same object!49}counter1.add(addAmount);
9counter1.increment();10counter1.add(addAmount5);11System.out.println("Traditional: " + counter1.getValue());public int getValue()
pass 1 of 256public int getValue() {57 return value7;58}counter2 ← ⟨Counter B⟩
10counter1.add(addAmount);11System.out.println("Traditional: " + counter1.getValue());1213// Chained way: single statement //?chained14Counter counter2→ ⟨Counter B⟩ = new Counter();15counter2.increment().increment().add(addAmount5);16System.out.println("Chained: " + counter2.getValue());outputTraditional: 7value ← 7
pass 2 of 246public Counter add(int amount5) {47 value→ 7 += amount5;48 return this; // Return the same object!49}counter2.increment().increment().add(addAmount);
14Counter counter2 = new Counter();15counter2.increment().increment().add(addAmount5);16System.out.println("Chained: " + counter2.getValue());public int getValue()
pass 2 of 256public int getValue() {57 return value7;58}builder ← ⟨MessageBuilder C⟩
15counter2.increment().increment().add(addAmount);16System.out.println("Chained: " + counter2.getValue());1718System.out.println("\n=== String Builder Pattern ===");1920// Build message fluently //?stringbuilder21MessageBuilder builder→ ⟨MessageBuilder C⟩ = new MessageBuilder();22String message = builder23 .append("Hello")24 .append(", ")25 .append("World")26 .append("!")27 .build();28System.out.println("Message: " + message);outputChained: 7 === String Builder Pattern ===public MessageBuilder append(String text)
pass 1 of 464public MessageBuilder append(String textHello) { //?append65 sb.append(textHello);66 return this; // Enables: append("a").append("b")67}All 4 passes — pass 1 is the card above pass text1 Hello 2 , 3 World 4 ! message ← Hello, World!
21 MessageBuilder builder = new MessageBuilder();22 String message→ Hello, World! = builder23 .append("Hello")24 .append(", ")25 .append("World")26 .append("!")27 .build();28 System.out.println("Message: " + messageHello, World!);29 30 System.out.println("\n=== Benefits ===");31 System.out.println("✓ More concise code");32 System.out.println("✓ Reads like natural language");33 System.out.println("✓ No need for temporary variables");34}outputMessage: Hello, World! === Benefits === ✓ More concise code ✓ Reads like natural language ✓ No need for temporary variables
addAmount ← 2, counter1 ← ⟨Counter A⟩
1public class MethodChaining {2 public static void main(String[] args) {3 System.out.println("=== Method Chaining ===\n");4 int addAmount→ 2 = 2;5 6 // Traditional way: separate statements7 Counter counter1→ ⟨Counter A⟩ = new Counter();8 counter1.increment();9 counter1.increment();output=== Method Chaining ===value ← 1
pass 1 of 440// Returns 'this' to enable chaining41public Counter increment() {42 value→ 1++;43 return this; // Return the same object!44}All 4 passes — pass 1 is the card above pass amountvalue1 — 0 → 1 2 — 1 → 2 3 — 0 → 1 4 2 1 → 2 counter1.increment();
7Counter counter1 = new Counter();8counter1.increment();9counter1.increment();10counter1.add(addAmount);counter1.add(addAmount);
8counter1.increment();9counter1.increment();10counter1.add(addAmount2);11System.out.println("Traditional: " + counter1.getValue());value ← 4
pass 1 of 246public Counter add(int amount2) {47 value→ 4 += amount2;48 return this; // Return the same object!49}counter1.add(addAmount);
9counter1.increment();10counter1.add(addAmount2);11System.out.println("Traditional: " + counter1.getValue());public int getValue()
pass 1 of 256public int getValue() {57 return value4;58}counter2 ← ⟨Counter B⟩
10counter1.add(addAmount);11System.out.println("Traditional: " + counter1.getValue());1213// Chained way: single statement14Counter counter2→ ⟨Counter B⟩ = new Counter();15counter2.increment().increment().add(addAmount2);16System.out.println("Chained: " + counter2.getValue());outputTraditional: 4value ← 4
pass 2 of 246public Counter add(int amount2) {47 value→ 4 += amount2;48 return this; // Return the same object!49}counter2.increment().increment().add(addAmount);
14Counter counter2 = new Counter();15counter2.increment().increment().add(addAmount2);16System.out.println("Chained: " + counter2.getValue());public int getValue()
pass 2 of 256public int getValue() {57 return value4;58}builder ← ⟨MessageBuilder C⟩
15counter2.increment().increment().add(addAmount);16System.out.println("Chained: " + counter2.getValue());1718System.out.println("\n=== String Builder Pattern ===");1920// Build message fluently21MessageBuilder builder→ ⟨MessageBuilder C⟩ = new MessageBuilder();22String message = builder23 .append("Hello")24 .append(", ")25 .append("World")26 .append("!")27 .build();28System.out.println("Message: " + message);outputChained: 4 === String Builder Pattern ===public MessageBuilder append(String text)
pass 1 of 464public MessageBuilder append(String textHello) {65 sb.append(textHello);66 return this; // Enables: append("a").append("b")67}All 4 passes — pass 1 is the card above pass text1 Hello 2 , 3 World 4 ! message ← Hello, World!
21 MessageBuilder builder = new MessageBuilder();22 String message→ Hello, World! = builder23 .append("Hello")24 .append(", ")25 .append("World")26 .append("!")27 .build();28 System.out.println("Message: " + messageHello, World!);29 30 System.out.println("\n=== Benefits ===");31 System.out.println("✓ More concise code");32 System.out.println("✓ Reads like natural language");33 System.out.println("✓ No need for temporary variables");34}outputMessage: Hello, World! === Benefits === ✓ More concise code ✓ Reads like natural language ✓ No need for temporary variables
addAmount ← 10, counter1 ← ⟨Counter A⟩
1public class MethodChaining {2 public static void main(String[] args) {3 System.out.println("=== Method Chaining ===\n");4 int addAmount→ 10 = 10;5 6 // Traditional way: separate statements7 Counter counter1→ ⟨Counter A⟩ = new Counter();8 counter1.increment();9 counter1.increment();output=== Method Chaining ===value ← 1
pass 1 of 440// Returns 'this' to enable chaining41public Counter increment() {42 value→ 1++;43 return this; // Return the same object!44}All 4 passes — pass 1 is the card above pass amountvalue1 — 0 → 1 2 — 1 → 2 3 — 0 → 1 4 10 1 → 2 counter1.increment();
7Counter counter1 = new Counter();8counter1.increment();9counter1.increment();10counter1.add(addAmount);counter1.add(addAmount);
8counter1.increment();9counter1.increment();10counter1.add(addAmount10);11System.out.println("Traditional: " + counter1.getValue());value ← 12
pass 1 of 246public Counter add(int amount10) {47 value→ 12 += amount10;48 return this; // Return the same object!49}counter1.add(addAmount);
9counter1.increment();10counter1.add(addAmount10);11System.out.println("Traditional: " + counter1.getValue());public int getValue()
pass 1 of 256public int getValue() {57 return value12;58}counter2 ← ⟨Counter B⟩
10counter1.add(addAmount);11System.out.println("Traditional: " + counter1.getValue());1213// Chained way: single statement14Counter counter2→ ⟨Counter B⟩ = new Counter();15counter2.increment().increment().add(addAmount10);16System.out.println("Chained: " + counter2.getValue());outputTraditional: 12value ← 12
pass 2 of 246public Counter add(int amount10) {47 value→ 12 += amount10;48 return this; // Return the same object!49}counter2.increment().increment().add(addAmount);
14Counter counter2 = new Counter();15counter2.increment().increment().add(addAmount10);16System.out.println("Chained: " + counter2.getValue());public int getValue()
pass 2 of 256public int getValue() {57 return value12;58}builder ← ⟨MessageBuilder C⟩
15counter2.increment().increment().add(addAmount);16System.out.println("Chained: " + counter2.getValue());1718System.out.println("\n=== String Builder Pattern ===");1920// Build message fluently21MessageBuilder builder→ ⟨MessageBuilder C⟩ = new MessageBuilder();22String message = builder23 .append("Hello")24 .append(", ")25 .append("World")26 .append("!")27 .build();28System.out.println("Message: " + message);outputChained: 12 === String Builder Pattern ===public MessageBuilder append(String text)
pass 1 of 464public MessageBuilder append(String textHello) {65 sb.append(textHello);66 return this; // Enables: append("a").append("b")67}All 4 passes — pass 1 is the card above pass text1 Hello 2 , 3 World 4 ! message ← Hello, World!
21 MessageBuilder builder = new MessageBuilder();22 String message→ Hello, World! = builder23 .append("Hello")24 .append(", ")25 .append("World")26 .append("!")27 .build();28 System.out.println("Message: " + messageHello, World!);29 30 System.out.println("\n=== Benefits ===");31 System.out.println("✓ More concise code");32 System.out.println("✓ Reads like natural language");33 System.out.println("✓ No need for temporary variables");34}outputMessage: Hello, World! === Benefits === ✓ More concise code ✓ Reads like natural language ✓ No need for temporary variables
return this allows obj.setX(1).setY(2).setZ(3).
Pass this to other methods
Give the current object to another method or class.
public class PassThis {
public static void main(String[] args) {
System.out.println("=== Passing 'this' to Methods ===\n");
// Create registrar and tasks
TaskRegistry registry = new TaskRegistry();
Task task1 = new Task("Learn Java", registry);
Task task2 = new Task("Practice coding", registry);
Task task3 = new Task("Build projects", registry);
System.out.println("=== Registry Status ===");
registry.showAll();
System.out.println("\n=== Completing a Task ===");
task2.complete();
System.out.println("\n=== Registry After Completion ===");
registry.showAll();
}
}
class Task {
private String name;
private boolean completed = false;
Task(String name, TaskRegistry registry) {
this.name = name;
registry.register(this);
}
void complete() {
completed = true;
System.out.println("Completed: " + name);
}
String getStatus() {
return name + (completed ? " [DONE]" : " [pending]");
}
}
class TaskRegistry {
private Task[] tasks = new Task[10];
private int count = 0;
void register(Task task) {
if (count < tasks.length) {
tasks[count++] = task;
System.out.println("Registered: " + task.getStatus());
}
}
void showAll() {
System.out.println("All tasks (" + count + "):");
for (int i = 0; i < count; i++) {
System.out.println(" " + (i + 1) + ". " + tasks[i].getStatus());
}
}
}
registry ← ⟨TaskRegistry A⟩
1public class PassThis {2 public static void main(String[] args) {3 System.out.println("=== Passing 'this' to Methods ===\n");4 5 // Create registrar and tasks //?setup6 TaskRegistry registry→ ⟨TaskRegistry A⟩ = new TaskRegistry();7 8 Task task1 = new Task("Learn Java", registry); //?createtask9 Task task2 = new Task("Practice coding", registry);output=== Passing 'this' to Methods ===this.name ← Learn Java
pass 1 of 327Task(String nameLearn Java, TaskRegistry registry⟨TaskRegistry A⟩) { //?taskctr28 this.name→ Learn Java = nameLearn Java;29 registry.register(this); //?passthis30}All 3 passes — pass 1 is the card above pass namethis.name1 Learn Java Learn Java 2 Practice coding Practice coding 3 Build projects Build projects void register(Task task)
pass 1 of 346void register(Task task⟨Task B⟩) { //?register47 if (count < tasks.length) {All 3 passes — pass 1 is the card above pass task1 ⟨Task B⟩ 2 ⟨Task C⟩ 3 ⟨Task D⟩ count ← 1
pass 1 of 346void register(Task task) { //?register47 if (count0 < tasks.length10) {48 tasks[count→ 1++] = task⟨Task B⟩;49 System.out.println("Registered: " + task.getStatus());50 }All 3 passes — pass 1 is the card above pass taskcount1 ⟨Task B⟩ 0 → 1 2 ⟨Task C⟩ 1 → 2 3 ⟨Task D⟩ 2 → 3 String getStatus()
pass 1 of 937String getStatus() {38 return nameLearn Java + (completedfalse ? " [DONE]" : " [pending]");39}All 9 passes — pass 1 is the card above pass namecompleted1 Learn Java false 2 Practice coding false 3 Build projects false 4 Learn Java false 5 Practice coding false 6 Build projects false 7 Learn Java false 8 Practice coding true 9 Build projects false task1 ← ⟨Task B⟩
8 Task task1→ ⟨Task B⟩ = new Task("Learn Java", registry); //?createtask9 Task task2 = new Task("Practice coding", registry);10 Task task3 = new Task("Build projects", registry);11 12 System.out.println("=== Registry Status ===");13 registry.showAll();14 15 System.out.println("\n=== Completing a Task ===");16 task2.complete(); //?complete17 18 System.out.println("\n=== Registry After Completion ===");19 registry.showAll();20 }21}2223class Task {24 private String name;25 private boolean completed = false;26 27 Task(String name, TaskRegistry registry) { //?taskctr28 this.name = name;29 registry.register(this); //?passthis30 }31 32 void complete() {33 completed = true;34 System.out.println("Completed: " + name);35 }36 37 String getStatus() {38 return name + (completed ? " [DONE]" : " [pending]");39 }40}4142class TaskRegistry {43 private Task[] tasks = new Task[10]; //?registry44 private int count = 0;45 46 void register(Task task) { //?register47 if (count < tasks.length) {48 tasks[count++] = task;49 System.out.println("Registered: " + task.getStatus());50 }outputRegistered: Learn Java [pending]task2 ← ⟨Task C⟩
8 Task task1 = new Task("Learn Java", registry); //?createtask9 Task task2→ ⟨Task C⟩ = new Task("Practice coding", registry);10 Task task3 = new Task("Build projects", registry);11 12 System.out.println("=== Registry Status ===");13 registry.showAll();14 15 System.out.println("\n=== Completing a Task ===");16 task2.complete(); //?complete17 18 System.out.println("\n=== Registry After Completion ===");19 registry.showAll();20 }21}2223class Task {24 private String name;25 private boolean completed = false;26 27 Task(String name, TaskRegistry registry) { //?taskctr28 this.name = name;29 registry.register(this); //?passthis30 }31 32 void complete() {33 completed = true;34 System.out.println("Completed: " + name);35 }36 37 String getStatus() {38 return name + (completed ? " [DONE]" : " [pending]");39 }40}4142class TaskRegistry {43 private Task[] tasks = new Task[10]; //?registry44 private int count = 0;45 46 void register(Task task) { //?register47 if (count < tasks.length) {48 tasks[count++] = task;49 System.out.println("Registered: " + task.getStatus());50 }outputRegistered: Practice coding [pending]task3 ← ⟨Task D⟩
9 Task task2 = new Task("Practice coding", registry);10 Task task3→ ⟨Task D⟩ = new Task("Build projects", registry);11 12 System.out.println("=== Registry Status ===");13 registry.showAll();14 15 System.out.println("\n=== Completing a Task ===");16 task2.complete(); //?complete17 18 System.out.println("\n=== Registry After Completion ===");19 registry.showAll();20 }21}2223class Task {24 private String name;25 private boolean completed = false;26 27 Task(String name, TaskRegistry registry) { //?taskctr28 this.name = name;29 registry.register(this); //?passthis30 }31 32 void complete() {33 completed = true;34 System.out.println("Completed: " + name);35 }36 37 String getStatus() {38 return name + (completed ? " [DONE]" : " [pending]");39 }40}4142class TaskRegistry {43 private Task[] tasks = new Task[10]; //?registry44 private int count = 0;45 46 void register(Task task) { //?register47 if (count < tasks.length) {48 tasks[count++] = task;49 System.out.println("Registered: " + task.getStatus());50 }outputRegistered: Build projects [pending] === Registry Status ===void showAll()
pass 1 of 253void showAll() {54 System.out.println("All tasks (" + count3 + "):");55 for (int i = 0; i < count; i++) {outputAll tasks (3):for (int i = 0; i < count; i++)
pass 1 of 654System.out.println("All tasks (" + count + "):");55for (int i0 = 0; i < count3; i++) {56 System.out.println(" " + (i0 + 1) + ". " + tasks[i]⟨Task B⟩.getStatus());57}All 6 passes — pass 1 is the card above pass itasks[i]1 0 ⟨Task B⟩ 2 1 ⟨Task C⟩ 3 2 ⟨Task D⟩ 4 0 ⟨Task B⟩ 5 1 ⟨Task C⟩ 6 2 ⟨Task D⟩ System.out.println(" " + (i + 1) + ". " + tasks[i].getStatus());
55for (int i = 0; i < count; i++) {56 System.out.println(" " + (i0 + 1) + ". " + tasks[i]⟨Task B⟩.getStatus());57}output 1. Learn Java [pending]System.out.println(" " + (i + 1) + ". " + tasks[i].getStatus());
55for (int i = 0; i < count; i++) {56 System.out.println(" " + (i1 + 1) + ". " + tasks[i]⟨Task C⟩.getStatus());57}output 2. Practice coding [pending]System.out.println(" " + (i + 1) + ". " + tasks[i].getStatus());
12 System.out.println("=== Registry Status ===");13 registry.showAll();14 15 System.out.println("\n=== Completing a Task ===");16 task2.complete(); //?complete17 18 System.out.println("\n=== Registry After Completion ===");19 registry.showAll();20 }21}2223class Task {24 private String name;25 private boolean completed = false;26 27 Task(String name, TaskRegistry registry) { //?taskctr28 this.name = name;29 registry.register(this); //?passthis30 }31 32 void complete() {33 completed = true;34 System.out.println("Completed: " + name);35 }36 37 String getStatus() {38 return name + (completed ? " [DONE]" : " [pending]");39 }40}4142class TaskRegistry {43 private Task[] tasks = new Task[10]; //?registry44 private int count = 0;45 46 void register(Task task) { //?register47 if (count < tasks.length) {48 tasks[count++] = task;49 System.out.println("Registered: " + task.getStatus());50 }51 }52 53 void showAll() {54 System.out.println("All tasks (" + count + "):");55 for (int i = 0; i < count; i++) {56 System.out.println(" " + (i2 + 1) + ". " + tasks[i]⟨Task D⟩.getStatus());57 }output 3. Build projects [pending] === Completing a Task ===completed ← true
15 System.out.println("\n=== Completing a Task ===");16 task2.complete(); //?complete17 18 System.out.println("\n=== Registry After Completion ===");19 registry.showAll();20 }21}2223class Task {24 private String name;25 private boolean completed = false;26 27 Task(String name, TaskRegistry registry) { //?taskctr28 this.name = name;29 registry.register(this); //?passthis30 }31 32 void complete() {33 completed→ true = true;34 System.out.println("Completed: " + namePractice coding);35 }outputCompleted: Practice coding === Registry After Completion ===void showAll()
pass 2 of 253void showAll() {54 System.out.println("All tasks (" + count3 + "):");55 for (int i = 0; i < count; i++) {outputAll tasks (3):System.out.println(" " + (i + 1) + ". " + tasks[i].getStatus());
55for (int i = 0; i < count; i++) {56 System.out.println(" " + (i0 + 1) + ". " + tasks[i]⟨Task B⟩.getStatus());57}output 1. Learn Java [pending]System.out.println(" " + (i + 1) + ". " + tasks[i].getStatus());
55for (int i = 0; i < count; i++) {56 System.out.println(" " + (i1 + 1) + ". " + tasks[i]⟨Task C⟩.getStatus());57}output 2. Practice coding [DONE]System.out.println(" " + (i + 1) + ". " + tasks[i].getStatus());
18 System.out.println("\n=== Registry After Completion ===");19 registry.showAll();20 }21}2223class Task {24 private String name;25 private boolean completed = false;26 27 Task(String name, TaskRegistry registry) { //?taskctr28 this.name = name;29 registry.register(this); //?passthis30 }31 32 void complete() {33 completed = true;34 System.out.println("Completed: " + name);35 }36 37 String getStatus() {38 return name + (completed ? " [DONE]" : " [pending]");39 }40}4142class TaskRegistry {43 private Task[] tasks = new Task[10]; //?registry44 private int count = 0;45 46 void register(Task task) { //?register47 if (count < tasks.length) {48 tasks[count++] = task;49 System.out.println("Registered: " + task.getStatus());50 }51 }52 53 void showAll() {54 System.out.println("All tasks (" + count + "):");55 for (int i = 0; i < count; i++) {56 System.out.println(" " + (i2 + 1) + ". " + tasks[i]⟨Task D⟩.getStatus());57 }output 3. Build projects [pending]
someMethod(this) passes the current object as an argument.
Call another constructor
Use this() to invoke a different constructor.
public class ThisConstructor {
public static void main(String[] args) {
System.out.println("=== this() Constructor Calls ===\n");
// Different ways to create Rectangle
Rectangle r1 = new Rectangle();
System.out.println("1. " + r1);
Rectangle r2 = new Rectangle(5); // Square
System.out.println("2. " + r2);
Rectangle r3 = new Rectangle(4, 6);
System.out.println("3. " + r3);
System.out.println("\n=== Notice Constructor Chain ===");
System.out.println("Each simpler constructor calls a more complete one.");
System.out.println("All eventually reach the main constructor.");
}
}
class Rectangle {
private double width;
private double height;
// Main constructor - all logic here
Rectangle(double width, double height) {
System.out.println(" [Main constructor: " + width + "x" + height + "]");
this.width = Math.max(0, width); // Validation
this.height = Math.max(0, height);
}
// Square constructor - delegates to main
Rectangle(double side) {
this(side, side); // Must be FIRST statement!
System.out.println(" [Square constructor]");
}
// Default constructor - delegates to square
Rectangle() {
this(1); // Unit square
System.out.println(" [Default constructor]");
}
@Override
public String toString() {
return "Rectangle " + width + "x" + height;
}
}
public static void main(String[] args)
1public class ThisConstructor {2 public static void main(String[] args) {3 System.out.println("=== this() Constructor Calls ===\n");4 5 // Different ways to create Rectangle //?create6 Rectangle r1 = new Rectangle();7 System.out.println("1. " + r1);output=== this() Constructor Calls ===this.width ← 1.0, this.height ← 1.0
pass 1 of 325// Main constructor - all logic here //?main26Rectangle(double width1.0, double height1.0) {27 System.out.println(" [Main constructor: " + width1.0 + "x" + height1.0 + "]");28 this.width→ 1.0 = Math.max(0, width1.0); // Validation29 this.height→ 1.0 = Math.max(0, height1.0);30}output [Main constructor: 1.0x1.0]All 3 passes — pass 1 is the card above pass widthheightsidethis.widththis.heightr1r2r31 1.0 1.0 1.0 1.0 1.0 Rectangle 1.0x1.0 — — 2 5.0 5.0 5.0 5.0 5.0 — Rectangle 5.0x5.0 — 3 4.0 6.0 — 4.0 6.0 — — Rectangle 4.0x6.0 Rectangle(double side)
pass 1 of 232// Square constructor - delegates to main //?square33Rectangle(double side1.0) {34 this(side, side); // Must be FIRST statement!35 System.out.println(" [Square constructor]");36}output [Square constructor]r1 ← Rectangle 1.0x1.0
5 // Different ways to create Rectangle //?create6 Rectangle r1→ Rectangle 1.0x1.0 = new Rectangle();7 System.out.println("1. " + r1Rectangle 1.0x1.0);8 9 Rectangle r2 = new Rectangle(5); // Square10 System.out.println("2. " + r2);11 12 Rectangle r3 = new Rectangle(4, 6);13 System.out.println("3. " + r3);14 15 System.out.println("\n=== Notice Constructor Chain ===");16 System.out.println("Each simpler constructor calls a more complete one.");17 System.out.println("All eventually reach the main constructor.");18 }19}2021class Rectangle {22 private double width;23 private double height;24 25 // Main constructor - all logic here //?main26 Rectangle(double width, double height) {27 System.out.println(" [Main constructor: " + width + "x" + height + "]");28 this.width = Math.max(0, width); // Validation29 this.height = Math.max(0, height);30 }31 32 // Square constructor - delegates to main //?square33 Rectangle(double side) {34 this(side, side); // Must be FIRST statement!35 System.out.println(" [Square constructor]");36 }37 38 // Default constructor - delegates to square //?default39 Rectangle() {40 this(1); // Unit square41 System.out.println(" [Default constructor]");42 }output [Default constructor] 1. Rectangle 1.0x1.0r2 ← Rectangle 5.0x5.0
pass 2 of 29 Rectangle r2→ Rectangle 5.0x5.0 = new Rectangle(5); // Square10 System.out.println("2. " + r2Rectangle 5.0x5.0);11 12 Rectangle r3 = new Rectangle(4, 6);13 System.out.println("3. " + r3);14 15 System.out.println("\n=== Notice Constructor Chain ===");16 System.out.println("Each simpler constructor calls a more complete one.");17 System.out.println("All eventually reach the main constructor.");18 }19}2021class Rectangle {22 private double width;23 private double height;24 25 // Main constructor - all logic here //?main26 Rectangle(double width, double height) {27 System.out.println(" [Main constructor: " + width + "x" + height + "]");28 this.width = Math.max(0, width); // Validation29 this.height = Math.max(0, height);30 }31 32 // Square constructor - delegates to main //?square33 Rectangle(double side5.0) {34 this(side, side); // Must be FIRST statement!35 System.out.println(" [Square constructor]");36 }output [Square constructor] 2. Rectangle 5.0x5.0
this(args) calls another constructor. Must be first line.
Builder pattern
Combine method chaining with a separate builder class.
public class BuilderPattern {
public static void main(String[] args) {
System.out.println("=== Builder Pattern ===\n");
// Build an email step by step
Email email = new EmailBuilder()
.from("alice@example.com")
.to("bob@example.com")
.subject("Meeting Tomorrow")
.body("Hi Bob,\nLet's meet at 10am.\n- Alice")
.priority(EmailBuilder.Priority.HIGH)
.build();
System.out.println(email);
System.out.println("\n=== Another Email ===");
// Simpler email with defaults
Email simple = new EmailBuilder()
.to("team@example.com")
.subject("Quick update")
.build();
System.out.println(simple);
System.out.println("\n=== Benefits ===");
System.out.println("✓ Optional parameters made easy");
System.out.println("✓ Readable, self-documenting");
System.out.println("✓ Immutable result object");
}
}
class EmailBuilder {
// Builder fields with defaults
private String from = "noreply@example.com";
private String to = "";
private String subject = "(no subject)";
private String body = "";
private Priority priority = Priority.NORMAL;
enum Priority { LOW, NORMAL, HIGH, URGENT }
// Each setter returns 'this'
public EmailBuilder from(String from) {
this.from = from;
return this; // Enable chaining
}
public EmailBuilder to(String to) {
this.to = to;
return this;
}
public EmailBuilder subject(String subject) {
this.subject = subject;
return this;
}
public EmailBuilder body(String body) {
this.body = body;
return this;
}
public EmailBuilder priority(Priority priority) {
this.priority = priority;
return this;
}
// Final build method creates the object
public Email build() {
if (to.isEmpty()) {
throw new IllegalStateException("'to' is required");
}
return new Email(from, to, subject, body, priority.name());
}
}
class Email {
private final String from, to, subject, body, priority;
Email(String from, String to, String subject, String body, String priority) {
this.from = from;
this.to = to;
this.subject = subject;
this.body = body;
this.priority = priority;
}
@Override
public String toString() {
return String.format(
"=== Email [%s] ===\nFrom: %s\nTo: %s\nSubject: %s\n---\n%s",
priority, from, to, subject, body.isEmpty() ? "(no body)" : body
);
}
}
public static void main(String[] args)
1public class BuilderPattern {2 public static void main(String[] args) {3 System.out.println("=== Builder Pattern ===\n");4 5 // Build an email step by step //?build6 Email email = new EmailBuilder()7 .from("alice@example.com")8 .to("bob@example.com")9 .subject("Meeting Tomorrow")10 .body("Hi Bob,\nLet's meet at 10am.\n- Alice")11 .priority(EmailBuilder.Priority.HIGH)12 .build();output=== Builder Pattern ===this.from ← alice@example.com
43// Each setter returns 'this' //?setters44public EmailBuilder from(String fromalice@example.com) {45 this.from→ alice@example.com = fromalice@example.com;46 return this; // Enable chaining47}this.to ← bob@example.com
pass 1 of 249public EmailBuilder to(String to) {50 this.to→ bob@example.com = tobob@example.com;51 return this;52}this.subject ← Meeting Tomorrow
pass 1 of 254public EmailBuilder subject(String subjectMeeting Tomorrow) {55 this.subject→ Meeting Tomorrow = subjectMeeting Tomorrow;56 return this;57}this.body ← Hi Bob, Let's meet at 10am. - Alice
59public EmailBuilder body(String bodyHi Bob, Let's meet at 10am. - Alice) {60 this.body→ Hi Bob, Let's meet at 10am. - Alice = bodyHi Bob, Let's meet at 10am. - Alice;61 return this;62}this.priority ← HIGH
64public EmailBuilder priority(Priority priorityHIGH) {65 this.priority→ HIGH = priorityHIGH;66 return this;67}this.from ← alice@example.com, this.to ← bob@example.com, this.subject ← Meeting Tomorrow
pass 1 of 25 // Build an email step by step //?build6 Email email→ === Email [HIGH] === From: alice@example.com To: bob@example.com Subject: Meeting Tomorrow --- Hi Bob, Let's meet at 10am. - Alice = new EmailBuilder()7 .from("alice@example.com")8 .to("bob@example.com")9 .subject("Meeting Tomorrow")10 .body("Hi Bob,\nLet's meet at 10am.\n- Alice")11 .priority(EmailBuilder.Priority.HIGH)12 .build();13 14 System.out.println(email=== Email [HIGH] === From: alice@example.com To: bob@example.com Subject: Meeting Tomorrow --- Hi Bob, Let's meet at 10am. - Alice);15 16 System.out.println("\n=== Another Email ===");17 18 // Simpler email with defaults //?simple19 Email simple = new EmailBuilder()20 .to("team@example.com")21 .subject("Quick update")22 .build();23 24 System.out.println(simple);25 26 System.out.println("\n=== Benefits ===");27 System.out.println("✓ Optional parameters made easy");28 System.out.println("✓ Readable, self-documenting");29 System.out.println("✓ Immutable result object");30 }31}3233class EmailBuilder {34 // Builder fields with defaults //?fields35 private String from = "noreply@example.com";36 private String to = "";37 private String subject = "(no subject)";38 private String body = "";39 private Priority priority = Priority.NORMAL;40 41 enum Priority { LOW, NORMAL, HIGH, URGENT }42 43 // Each setter returns 'this' //?setters44 public EmailBuilder from(String from) {45 this.from = from;46 return this; // Enable chaining47 }48 49 public EmailBuilder to(String to) {50 this.to = to;51 return this;52 }53 54 public EmailBuilder subject(String subject) {55 this.subject = subject;56 return this;57 }58 59 public EmailBuilder body(String body) {60 this.body = body;61 return this;62 }63 64 public EmailBuilder priority(Priority priority) {65 this.priority = priority;66 return this;67 }68 69 // Final build method creates the object //?buildmethod70 public Email build() {71 if (to.isEmpty()) {72 throw new IllegalStateException("'to' is required");73 }74 return new Email(from, to, subject, body, priority.name());75 }76}7778class Email {79 private final String from, to, subject, body, priority; //?emailfields80 81 Email(String fromalice@example.com, String to, String subjectMeeting Tomorrow, String bodyHi Bob, Let's meet at 10am. - Alice, String priorityHIGH) {82 this.from→ alice@example.com = fromalice@example.com;83 this.to→ bob@example.com = tobob@example.com;84 this.subject→ Meeting Tomorrow = subjectMeeting Tomorrow;85 this.body→ Hi Bob, Let's meet at 10am. - Alice = bodyHi Bob, Let's meet at 10am. - Alice;86 this.priority→ HIGH = priorityHIGH;87 }output=== Email [HIGH] === From: alice@example.com To: bob@example.com Subject: Meeting Tomorrow --- Hi Bob, Let's meet at 10am. - Alice === Another Email ===this.to ← team@example.com
pass 2 of 249public EmailBuilder to(String to) {50 this.to→ team@example.com = toteam@example.com;51 return this;52}this.subject ← Quick update
pass 2 of 254public EmailBuilder subject(String subjectQuick update) {55 this.subject→ Quick update = subjectQuick update;56 return this;57}this.from ← noreply@example.com, this.to ← team@example.com, this.subject ← Quick update
pass 2 of 218 // Simpler email with defaults //?simple19 Email simple→ === Email [NORMAL] === From: noreply@example.com To: team@example.com Subject: Quick update --- (no body) = new EmailBuilder()20 .to("team@example.com")21 .subject("Quick update")22 .build();23 24 System.out.println(simple=== Email [NORMAL] === From: noreply@example.com To: team@example.com Subject: Quick update --- (no body));25 26 System.out.println("\n=== Benefits ===");27 System.out.println("✓ Optional parameters made easy");28 System.out.println("✓ Readable, self-documenting");29 System.out.println("✓ Immutable result object");30 }31}3233class EmailBuilder {34 // Builder fields with defaults //?fields35 private String from = "noreply@example.com";36 private String to = "";37 private String subject = "(no subject)";38 private String body = "";39 private Priority priority = Priority.NORMAL;40 41 enum Priority { LOW, NORMAL, HIGH, URGENT }42 43 // Each setter returns 'this' //?setters44 public EmailBuilder from(String from) {45 this.from = from;46 return this; // Enable chaining47 }48 49 public EmailBuilder to(String to) {50 this.to = to;51 return this;52 }53 54 public EmailBuilder subject(String subject) {55 this.subject = subject;56 return this;57 }58 59 public EmailBuilder body(String body) {60 this.body = body;61 return this;62 }63 64 public EmailBuilder priority(Priority priority) {65 this.priority = priority;66 return this;67 }68 69 // Final build method creates the object //?buildmethod70 public Email build() {71 if (to.isEmpty()) {72 throw new IllegalStateException("'to' is required");73 }74 return new Email(from, to, subject, body, priority.name());75 }76}7778class Email {79 private final String from, to, subject, body, priority; //?emailfields80 81 Email(String fromnoreply@example.com, String to, String subjectQuick update, String body(empty), String priorityNORMAL) {82 this.from→ noreply@example.com = fromnoreply@example.com;83 this.to→ team@example.com = toteam@example.com;84 this.subject→ Quick update = subjectQuick update;85 this.body→ (empty) = body(empty);86 this.priority→ NORMAL = priorityNORMAL;87 }output=== Email [NORMAL] === From: noreply@example.com To: team@example.com Subject: Quick update --- (no body) === Benefits === ✓ Optional parameters made easy ✓ Readable, self-documenting ✓ Immutable result object
Builder accumulates settings, then creates the final object.
Exercise: CompleteExample.java
Comprehensive example combining all uses of this