Skip to content
beginnerPhase 11 · Java OOP

Encapsulation

Use access modifiers, getters, and setters for data hiding.

45m
2 problems
Topic Progress0%

Access Modifiers

Access Modifiers in Java

Access modifiers control visibility of classes, methods, and variables.

Four Access Levels

public class AccessExample {
    public int publicVar = 1;       // Everywhere
    protected int protectedVar = 2; // Same package + subclasses
    int defaultVar = 3;             // Same package only
    private int privateVar = 4;     // This class only
}

Package Structure

// File: com/example/Person.java
package com.example;

public class Person {
    public String name;      // Accessible everywhere
    protected int age;       // Accessible in com.example + subclasses
    String email;            // Accessible in com.example only
    private String password; // Accessible in Person only
}

// File: com/example/Student.java
package com.example;

public class Student extends Person {
    public void test() {
        System.out.println(name);      // OK
        System.out.println(age);       // OK (subclass)
        System.out.println(email);     // OK (same package)
        // System.out.println(password); // ERROR!
    }
}

// File: com/other/Main.java
package com.other;

public class Main {
    public void test() {
        Person p = new Person();
        System.out.println(p.name);      // OK
        // System.out.println(p.age);    // ERROR!
        // System.out.println(p.email);  // ERROR!
        // System.out.println(p.password); // ERROR!
    }
}

Summary Table

Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
default Y Y N N
private Y N N N

Getters and Setters

Getters and Setters

Getter and setter methods provide controlled access to private fields.

Basic Getters and Setters

public class Person {
    private String name;
    private int age;
    
    // Getter
    public String getName() {
        return name;
    }
    
    // Setter
    public void setName(String name) {
        this.name = name;
    }
    
    // Getter
    public int getAge() {
        return age;
    }
    
    // Setter with validation
    public void setAge(int age) {
        if (age >= 0 && age <= 150) {
            this.age = age;
        } else {
            throw new IllegalArgumentException("Invalid age");
        }
    }
}

Boolean Getters

public class Employee {
    private boolean active;
    private boolean isManager;
    
    // For boolean, use is prefix
    public boolean isActive() {
        return active;
    }
    
    // For isXxx fields, use getXxx
    public boolean getIsManager() {
        return isManager;
    }
    
    public void setActive(boolean active) {
        this.active = active;
    }
}

Read-Only Properties

public class Circle {
    private double radius;
    private final String id;  // Set only in constructor
    
    public Circle(double radius, String id) {
        this.radius = radius;
        this.id = id;
    }
    
    // Getter only - no setter
    public double getRadius() {
        return radius;
    }
    
    public String getId() {
        return id;
    }
    
    // Calculated property
    public double getArea() {
        return Math.PI * radius * radius;
    }
}

Builder Pattern with Setters

public class User {
    private String name;
    private int age;
    private String email;
    
    private User() { }
    
    public static Builder builder() {
        return new Builder();
    }
    
    public static class Builder {
        private User user = new User();
        
        public Builder name(String name) {
            user.name = name;
            return this;
        }
        
        public Builder age(int age) {
            user.age = age;
            return this;
        }
        
        public Builder email(String email) {
            user.email = email;
            return this;
        }
        
        public User build() {
            return user;
        }
    }
}

User user = User.builder()
    .name("Alice")
    .age(25)
    .email("alice@example.com")
    .build();

Data Hiding

Data Hiding Benefits

Data hiding protects internal state and provides controlled access.

Why Hide Data?

public class BankAccount {
    private double balance;
    
    // Without encapsulation - anyone can manipulate
    // public double balance;  // DANGEROUS!
    // account.balance = -1000; // No validation!
    
    // With encapsulation - controlled access
    public double getBalance() {
        return balance;
    }
    
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
        }
    }
    
    public void withdraw(double amount) {
        if (amount > 0 && amount <= balance) {
            balance -= amount;
        }
    }
}

Invariant Protection

public class Date {
    private int day;
    private int month;
    private int year;
    
    public void setDay(int day) {
        if (day < 1 || day > 31) {
            throw new IllegalArgumentException("Invalid day");
        }
        this.day = day;
    }
    
    public void setMonth(int month) {
        if (month < 1 || month > 12) {
            throw new IllegalArgumentException("Invalid month");
        }
        this.month = month;
    }
}

Implementation Flexibility

public class Employee {
    private String firstName;
    private String lastName;
    
    // Can change internal representation without affecting clients
    public String getFullName() {
        return firstName + " " + lastName;
    }
    
    // Later, change to single name field
    // Client code still works!
}

Validation

public class User {
    private String email;
    
    public void setEmail(String email) {
        if (email == null || !email.contains("@")) {
            throw new IllegalArgumentException("Invalid email");
        }
        this.email = email.toLowerCase();
    }
}

Best Practices

// 1. Always make fields private
private int count;

// 2. Provide public getters/setters
public int getCount() { return count; }

// 3. Validate in setters
public void setCount(int count) {
    if (count < 0) throw new IllegalArgumentException();
    this.count = count;
}

// 4. Make classes final if not meant to be extended
public final class ImmutableClass { }

Practice Problems

0/2solved
Design Phone Directory
Class Design

Design a phone directory that stores phone numbers for given numbers.

Example:

Input: add(1, "Alice"), get(1)

Output: Alice

Basic CRUD operations

Optimal Solution — O(1) time, O(n) space

Use HashMap for O(1) operations.

class PhoneDirectory {
    private Map<Integer, String> contacts;
    public PhoneDirectory() { contacts = new HashMap<>(); }
    public void add(int num, String name) { contacts.put(num, name); }
    public String get(int num) { return contacts.getOrDefault(num, null); }
}

Edge Cases:

  • Add duplicate
  • Get non-existent
  • Empty directory
Design Logger System
Class Design

Design a logger that prints messages with timestamps.

Example:

Input: log("msg1", 1), log("msg2", 2)

Output: true

Logger stores messages

Optimal Solution — O(1) time, O(n) space

Use HashSet to track messages.

class Logger {
    private Set<String> messages;
    public Logger() { messages = new HashSet<>(); }
    public boolean shouldPrint(int timestamp, String message) {
        if (messages.add(message)) { return true; }
        return false;
    }
}

Edge Cases:

  • Duplicate message
  • Empty message
  • Same timestamp

Quiz

1. Which access modifier allows access only within the same class?

Question 1 options

2. What is the benefit of encapsulation?

Question 2 options

3. What is a getter method?

Question 3 options

4. What is the primary purpose of Encapsulation?

Question 4 options

Flashcards

Question

What is encapsulation?

Answer

Bundling data with methods that operate on that data, hiding internal state behind public interfaces.

Question

What is the difference between public and private?

Answer

public is accessible everywhere. private is only accessible within the same class.

Question

Why use getters and setters?

Answer

To control access to private fields, add validation, and maintain encapsulation.

Question

What is Encapsulation?

Answer

Encapsulation is a key concept in Java programming.

Question

When to use Encapsulation?

Answer

Use Encapsulation when building production systems that require reliability, scalability, and maintainability.

Revision Notes

Key Takeaways

  • 1.Always make fields private
  • 2.Use getters/setters for access
  • 3.Validate in setters
  • 4.Encapsulation enables flexibility

Interview Tips

  • Know all four access modifiers
  • Understand when to use each modifier
  • Practice designing encapsulated classes
  • Know benefits of data hiding

Cheat Sheet

Cheat Sheet

  • public: everywhere
  • protected: same package + subclasses
  • default: same package
  • private: same class
  • Getter: returns field value
  • Setter: sets field value with validation