Home Encapsulation Immutable Scope Static Passing Objects Array of Objects Aggregation GC Strings Wrappers

Week 5: Thinking in Objects

Liang Chapters 9 & 10: Encapsulation, Immutable Objects, Scope, Static Members, Passing Objects, Arrays of Objects, Aggregation, Garbage Collection, Strings, Wrappers, and BigDecimal

Data Field Encapsulation

Encapsulation means making data fields private and providing public getter and setter methods to access and modify them. This protects data from invalid states and hides internal implementation. (Liang, Section 9.9)

Encapsulated Class

public class Circle { private double radius; // private — cannot be accessed directly public Circle(double radius) { this.radius = radius; } // Getter public double getRadius() { return radius; } // Setter with validation public void setRadius(double radius) { if (radius >= 0) this.radius = radius; } public double getArea() { return radius * radius * Math.PI; } }

Without vs. With Encapsulation

// Without Encapsulation — dangerous! c.radius = -5; // Invalid but no error // With Encapsulation — safe! c.setRadius(-5); // Setter rejects it, radius stays unchanged

Naming Convention

For a field xyz: getter is getXyz(), setter is setXyz(value). For boolean fields: getter is isXyz(). (Liang, Section 9.9)

Q1: Why make data fields private?
A) To make the program run faster
B) To protect data and control access through methods
C) To prevent creating objects
D) To allow access from any class
Private fields prevent direct access from outside. Access is controlled through getter/setter methods, enabling validation and data protection. (Liang, Section 9.9)
Q2: What is the correct getter name for a boolean field called active?
A) getActive()
B) isActive()
C) active()
D) hasActive()
For boolean fields, the JavaBeans convention uses is instead of get. (Liang, Section 9.9)

Section Score

0 / 0

Immutable Objects and Classes

An immutable object is an object whose state cannot be changed after it is created. An immutable class is a class whose objects are immutable. The String class is a well-known example. (Liang, Section 9.10)

Requirements for an Immutable Class

Rules

1. All data fields must be private.

2. No setter (mutator) methods.

3. No methods that can modify the object's state.

4. The class itself can be declared final to prevent subclasses from adding mutability.

Immutable Class Example

public final class ImmutableCircle { private double radius; public ImmutableCircle(double radius) { this.radius = radius; } // Only getter — NO setter public double getRadius() { return radius; } public double getArea() { return radius * radius * Math.PI; } }

Once an ImmutableCircle is created, its radius can never be changed. To get a circle with a different radius, you must create a new object.

Q1: Which of these makes a class mutable (NOT immutable)?
A) Having only private fields
B) Having a public setter method
C) Having only getter methods
D) Declaring the class final
A setter method allows modification of the object's state after creation, which breaks immutability. (Liang, Section 9.10)

Section Score

0 / 0

The Scope of Variables

The scope of a variable determines where in the program it can be accessed. Java has three types of variable scope: local variables, instance variables, and class (static) variables. (Liang, Section 9.8)

Variable Scope Types

TypeDeclared InScopeLifetime
LocalInside a method or blockFrom declaration to end of blockMethod execution
InstanceInside a class (no static)Entire classObject's lifetime
Class (static)Inside a class with staticEntire classProgram's lifetime

Scope Example

public class ScopeDemo { private int x = 10; // Instance variable — accessible everywhere in the class private static int count = 0; // Class variable — shared by all objects public void myMethod() { int y = 20; // Local variable — only visible in this method System.out.println(x); // OK: instance variable System.out.println(y); // OK: local variable } public void anotherMethod() { System.out.println(x); // OK: instance variable // System.out.println(y); // ERROR: y is not in scope here } }

Shadowing

If a local variable has the same name as an instance variable, the local variable shadows (hides) the instance variable within that scope. Use this.variableName to refer to the instance variable. (Liang, Section 9.8)

Q1: What is the scope of a local variable?
A) The entire class
B) From its declaration to the end of the block it is declared in
C) The entire program
D) Only the line it is declared on
A local variable's scope starts at its declaration and ends at the closing brace of the block in which it is declared. (Liang, Section 9.8)

Trace the Code

public class Test { int x = 1; public void method() { int x = 10; System.out.println("local: " + x); System.out.println("instance: " + this.x); } } // new Test().method();

What are the two lines of output?

Section Score

0 / 0

Static Variables, Constants, and Methods

A static member belongs to the class, not to any particular object. Static variables are shared by all instances. Static constants are declared with static final. (Liang, Section 9.7)

Static Variable & Constant

public class Circle { private double radius; private static int numberOfObjects = 0; // Shared by ALL objects public static final double PI = 3.14159; // Static constant public Circle(double radius) { this.radius = radius; numberOfObjects++; // Increment shared counter } public static int getNumberOfObjects() { return numberOfObjects; } }

Instance vs. Static

InstanceStatic
Belongs toEach objectThe class
Accessobj.memberClassName.member
MemoryOne copy per objectOne copy shared by all

Important Rules

• A static method cannot access instance variables or use this.

• An instance method can access both static and instance members.

• Static constants (static final) should use UPPER_CASE naming. (Liang, Section 9.7)

Q1: Can a static method access an instance variable directly?
A) Yes, always
B) No — static methods belong to the class, not any specific object
C) Only if the variable is public
D) Only if using this
A static method has no this reference and cannot access instance members directly. It can only access static members. (Liang, Section 9.7)

Trace the Code

Circle a = new Circle(1); Circle b = new Circle(2); Circle c = new Circle(3); System.out.println(Circle.getNumberOfObjects());

What is the output?

Section Score

0 / 0

Passing Objects to Methods

When you pass an object to a method, you are passing the reference (memory address), not a copy of the object. This means the method can modify the original object's data fields. This is different from passing primitive types, which passes a copy of the value. (Liang, Section 9.6)

Passing Primitives vs. Objects

public class PassingDemo { public static void changePrimitive(int x) { x = 100; // Changes the LOCAL copy only } public static void changeObject(Circle c) { c.setRadius(100); // Changes the ORIGINAL object! } public static void main(String[] args) { int num = 5; changePrimitive(num); System.out.println(num); // Still 5 — primitive was copied Circle c = new Circle(5); changeObject(c); System.out.println(c.getRadius()); // 100.0 — object was modified! } }

Comparison

Passing PrimitivesPassing Objects
A copy of the value is passedA copy of the reference is passed
Changes inside the method do NOT affect the originalChanges to the object's fields DO affect the original
int x = 5; change(x);Circle c = new Circle(5); change(c);
Q1: When you pass an object to a method, what is actually passed?
A) A copy of the entire object
B) A copy of the reference (memory address) to the object
C) The variable name
D) Nothing — objects cannot be passed
Java passes a copy of the reference. Both the caller and the method have references pointing to the same object in memory. (Liang, Section 9.6)

Trace the Code

public static void swap(Circle a, Circle b) { Circle temp = a; a = b; b = temp; } Circle x = new Circle(1); Circle y = new Circle(2); swap(x, y); System.out.println(x.getRadius() + " " + y.getRadius());

What is the output? (Hint: swapping references inside a method does NOT affect the caller)

Section Score

0 / 0

Array of Objects

You can create an array that holds references to objects. Each element of the array is a reference variable that must be initialized with new before use. (Liang, Section 9.11)

Creating an Array of Objects

// Step 1: Declare the array Circle[] circles = new Circle[3]; // Array of 3 references (all null) // Step 2: Create each object circles[0] = new Circle(1.0); circles[1] = new Circle(2.0); circles[2] = new Circle(3.0); // Step 3: Use the objects for (Circle c : circles) { System.out.println("Radius: " + c.getRadius() + ", Area: " + c.getArea()); }

Common Mistake

Circle[] circles = new Circle[3]; creates the array, but each element is null. You must create each object individually with new Circle(). Accessing circles[0].getArea() before initialization causes NullPointerException!

Shorthand Initialization

Circle[] circles = { new Circle(1.0), new Circle(2.0), new Circle(3.0) };
Q1: After Circle[] c = new Circle[5];, what is c[0]?
A) A Circle with radius 0
B) null
C) A Circle with radius 1
D) Compilation error
Creating the array only allocates space for references. Each element defaults to null until you assign an object with new. (Liang, Section 9.11)

Trace the Code

Circle[] arr = new Circle[3]; for (int i = 0; i < arr.length; i++) { arr[i] = new Circle(i + 1); } System.out.println(arr[2].getRadius());

What is the output?

Section Score

0 / 0

Class Aggregation and Composition

Aggregation and composition model "has-a" relationships between objects. A class can have a data field that references another object. The difference is about ownership and lifecycle. (Liang, Section 9.11)

Aggregation — Object Passed In

In aggregation, the contained object is created outside and passed to the container. It can exist independently.

class Professor { String name; public Professor(String name) { this.name = name; } } class Department { String name; Professor head; // Aggregation public Department(String name, Professor head) { this.name = name; this.head = head; // Professor is PASSED IN } } // Usage: Professor p = new Professor("Dr. Smith"); // Created outside Department d = new Department("CS", p); // Passed in // If d is destroyed, p still exists

Composition — Object Created Inside

In composition, the contained object is created inside the container. Its lifecycle depends on the container.

class Engine { String type; public Engine(String type) { this.type = type; } } class Car { String make; Engine engine; // Composition public Car(String make, String engineType) { this.make = make; this.engine = new Engine(engineType); // Engine created INSIDE } } // Usage: Car c = new Car("Toyota", "V6"); // If c is destroyed, the engine is also destroyed

Comparison

AggregationComposition
RelationshipWeak "has-a"Strong "has-a"
Object creationCreated outside, passed inCreated inside the container
LifecycleIndependentDependent on container
UMLHollow diamond ◊Filled diamond ♦
Q1: What is the key difference between aggregation and composition?
A) Aggregation uses inheritance; composition does not
B) In composition, the contained object is created inside and depends on the container; in aggregation, it is passed in and independent
C) There is no difference
D) Aggregation uses new inside; composition does not
Composition: object created inside with new (strong ownership). Aggregation: object passed in from outside (weak ownership, independent lifecycle). (Liang, Section 9.11)

Section Score

0 / 0

Garbage Collection

Java automatically reclaims memory occupied by objects that are no longer referenced. This process is called garbage collection. You don't need to manually free memory like in C/C++. (Liang, Section 9.10)

When Does an Object Become Garbage?

Circle c1 = new Circle(1); Circle c2 = new Circle(2); c1 = c2; // The Circle(1) object is now unreachable — eligible for GC c2 = null; // c2 no longer references Circle(2), but c1 still does // Circle(2) is NOT garbage — c1 still points to it

Key Facts

• An object becomes eligible for garbage collection when no references point to it.

• The JVM runs the garbage collector automatically — you cannot force it.

System.gc() only suggests that the JVM run GC — it is not guaranteed.

• Setting a reference to null does not immediately destroy the object.

Q1: When is an object eligible for garbage collection?
A) When you call delete on it
B) When you set it to null
C) When no references point to it anywhere in the program
D) When the method ends
An object is eligible for GC only when there are no live references to it. Setting one reference to null doesn't make it garbage if another reference still points to it. (Liang, Section 9.10)

Trace the Code

Circle a = new Circle(1); // Object A Circle b = new Circle(2); // Object B Circle c = a; // c points to Object A a = b; // a now points to Object B b = null; // b points to nothing // How many objects are eligible for GC?

How many objects are eligible for garbage collection? (Hint: Object A is still referenced by c, Object B is still referenced by a)

Section Score

0 / 0

The String Class

Strings are immutable objects in Java. Any operation that appears to modify a String creates a new String object. (Liang, Section 10.10)

Common String Methods

MethodDescriptionExample
length()Number of characters"Hello".length()5
charAt(i)Character at index i"Hello".charAt(1)'e'
substring(i, j)Substring from i to j-1"Hello".substring(1, 4)"ell"
equals(s)Compare content"Hi".equals("hi")false
equalsIgnoreCase(s)Compare ignoring case"Hi".equalsIgnoreCase("hi")true
indexOf(s)First index of s"Hello".indexOf("ll")2
toUpperCase()To uppercase"hello".toUpperCase()"HELLO"
trim()Remove whitespace" Hi ".trim()"Hi"

== vs. equals()

== compares references. .equals() compares content. Always use .equals() to compare string values!

Q1: What does "immutable" mean for Strings?
A) Strings can be changed after creation
B) Once created, a String's content cannot be modified
C) Strings cannot be compared
D) Strings are stored on the stack
Strings are immutable. Methods like toUpperCase() return a new String — the original is unchanged. (Liang, Section 10.10)

Trace the Code

String s1 = "Java"; String s2 = "Java"; String s3 = new String("Java"); System.out.println(s1 == s2); System.out.println(s1 == s3); System.out.println(s1.equals(s3));

What are the three lines of output?

Section Score

0 / 0

Wrapper Classes

Wrapper classes let you use primitives as objects. Java automatically converts between them: autoboxing (primitive → wrapper) and unboxing (wrapper → primitive). (Liang, Section 10.7)

Mapping

PrimitiveWrapperPrimitiveWrapper
intIntegerfloatFloat
doubleDoublecharCharacter
longLongbooleanBoolean

Autoboxing & Unboxing

Integer obj = 100; // Autoboxing: int → Integer int prim = obj; // Unboxing: Integer → int int x = Integer.parseInt("42"); // String → int double d = Double.parseDouble("3.14"); // String → double
Q1: What is autoboxing?
A) Automatic conversion from a primitive to its wrapper object
B) Automatic conversion from a wrapper to a primitive
C) Converting a String to a number
D) Creating an array of objects
Autoboxing: primitive → wrapper. Unboxing: wrapper → primitive. Both happen automatically. (Liang, Section 10.7)

Section Score

0 / 0

BigInteger and BigDecimal

BigInteger handles arbitrarily large integers. BigDecimal provides exact decimal arithmetic, avoiding floating-point errors. Use methods (add, subtract, multiply, divide) instead of operators. (Liang, Section 10.9)

BigDecimal Example

import java.math.BigDecimal; System.out.println(0.1 + 0.2); // 0.30000000000000004 (imprecise!) BigDecimal d1 = new BigDecimal("0.1"); BigDecimal d2 = new BigDecimal("0.2"); System.out.println(d1.add(d2)); // 0.3 (exact!)

Important

Always create BigDecimal from a String, not a double. new BigDecimal(0.1) captures the imprecise double value. Use new BigDecimal("0.1") instead. (Liang, Section 10.9)

Q1: How do you add two BigInteger values a and b?
A) a + b
B) a.add(b)
C) BigInteger.add(a, b)
D) add(a, b)
BigInteger/BigDecimal are objects — you must use their instance methods. Operators like + don't work. (Liang, Section 10.9)

Section Score

0 / 0

Week 5

Encapsulation Immutable Objects Scope of Variables Static Members Passing Objects Array of Objects Aggregation Garbage Collection String Class Wrappers BigInteger