Back

Activity 4.3 Encapsulation

divider

Introduction

Activity 4.3

Encapsulation

Topics

  • Private instance variables
  • Accessors (getters) and mutators (setters)
  • Protecting object state
  • Enforcing invariants
  • Correct access through methods

The Problem With Public Variables

Without encapsulation, any code can change your object's data incorrectly.

class Student
{
String name;
int gradeLevel;
double gpa;
}

Nothing prevents another class from assigning invalid values.

Encapsulation Fixes This

Encapsulation means keeping instance variables private and providing controlled access through methods.

  • private variables hide data
  • getters return values
  • setters modify values safely

Encapsulated Class Example

              
                
class Student
{
// Instance variables should be private
private String name;
private int gradeLevel;
private double gpa;
public Student(String name, int gradeLevel, double gpa)
{
this.name = name;
this.gradeLevel = gradeLevel;
setGpa(gpa); // use setter for validation
}
// Accessors (getters)
public String getName()
{
return name;
}
public int getGradeLevel()
{
return gradeLevel;
}
public double getGpa()
{
return gpa;
}
// Mutators (setters)
public void setName(String name)
{
this.name = name;
}
public void setGradeLevel(int gradeLevel)
{
this.gradeLevel = gradeLevel;
}
public void setGpa(double gpa)
{
if (gpa < 0.0 || gpa > 4.0)
{
this.gpa = 0.0; // enforce invariant
}
else
{
this.gpa = gpa;
}
}
}

What Is an Invariant?

An invariant is a rule or condition that must always be true about an object's internal state.

  • Constructors establish the invariant when the object is created.
  • Setters and methods preserve the invariant by blocking invalid changes.
Examples
  • 0.0 ≤ gpa ≤ 4.0
  • balance ≥ 0
  • currentHp ≤ maxHp

In short: Invariants ensure your objects always remain in a valid state.

Why Encapsulation Matters

  • Protects object integrity
  • Prevents invalid data
  • Keeps control inside the class
  • Essential for AP CSA FRQs

Key Terms

Encapsulation
Protecting data by restricting direct access to instance variables.
private
Access modifier preventing use outside the class.
public
Access modifier allowing use outside the class.

Key Terms

Accessor (Getter)
A method that returns the value of a private variable.
Mutator (Setter)
A method that changes the value of a private variable.
Invariant
A rule or constraint that must always be true for the object.

'F' → Fullscreen

Objectives

  • icon Use private to protect instance variables
  • icon Write getters and setters
  • icon Explain why encapsulation prevents invalid state
  • icon Apply encapsulation in class design
divider

Activity Tasks

  • icon Create a new project named 4-3-Encapsulation.
  • icon Complete each task individually.

Task 1: Movie Class (Encapsulated)

Implement getters and setters for the Movie class.

Step 1 - Movie.java

Movie.java
class Movie
{
private String title;
private String director;
public Movie()
{
title = "Untitled";
director = "Unknown";
}
public Movie(String title, String director)
{
this.title = title;
this.director = director;
}
public String getTitle()
{
return title;
}
public String getDirector()
{
return director;
}
public void setTitle(String title)
{
this.title = title;
}
public void setDirector(String director)
{
this.director = director;
}
}

Step 2 - Program.java

Program.java
public class Program
{
public static void main(String[] args)
{
Movie m = new Movie("Inception", "Christopher Nolan");
System.out.println(m.getTitle());
System.out.println(m.getDirector());
m.setTitle("Interstellar");
System.out.println(m.getTitle());
}
}

Task 2: Bank Account Invariants

Modify this BankAccount class to enforce correct behavior through encapsulation.

Step 1 - BankAccount.java

BankAccount.java
class BankAccount
{
private String owner;
private double balance;
public BankAccount(String owner, double balance)
{
this.owner = owner;
// Validate initial balance
if (balance < 0)
{
this.balance = 0;
}
else
{
this.balance = balance;
}
}
public String getOwner()
{
return owner;
}
public double getBalance()
{
return balance;
}
// Controlled deposit
public void deposit(double amount)
{
if (amount > 0)
{
balance += amount;
}
}
// Controlled withdrawal
public void withdraw(double amount)
{
if (amount > 0 && amount <= balance)
{
balance -= amount;
}
}
}

Step 2 - Program.java

Program.java
public class Program
{
public static void main(String[] args)
{
// Movie test code ommitted.
BankAccount acct = new BankAccount("Alex", 100);
acct.deposit(50);
acct.withdraw(30);
System.out.println(acct.getOwner() + " - Balance: $" + acct.getBalance());
}
}
divider

Sample Output

Sample Output
Inception
Christopher Nolan
Interstellar
Alex - Balance: $120.0
divider

Reflection Questions

Write your answers as comments in your Program.java file.

  1. Why should instance variables almost always be private in Java?
  2. What problem do setters prevent when validating data?
  3. Why is it dangerous to modify private variables directly from outside the class?
  4. Describe an invariant your class enforces. How does your setter or constructor enforce it?
  5. In your own words, explain the difference between an accessor and a mutator.
divider

Submission

Submit your completed class files and reflection answers to the appropriate dropbox.

Activity Complete