Skip to main content
Access Modifiers
  1. Resources/
  2. Study Materials/
  3. Information & Communication Technology Engineering/
  4. ICT Semester 4/
  5. Java Programming (4343203)/
  6. Java Programming Slidev Presentations/

Access Modifiers

·
Milav Dabgar
Author
Milav Dabgar
Experienced lecturer in the electrical and electronic manufacturing industry. Skilled in Embedded Systems, Image Processing, Data Science, MATLAB, Python, STM32. Strong education professional with a Master’s degree in Communication Systems Engineering from L.D. College of Engineering - Ahmedabad.
Table of Contents

Access Modifiers
#

Lecture 12
#

Java Programming (4343203)
Diploma in ICT - Semester IV
Gujarat Technological University

Press Space for next page

layout: default
#

Learning Objectives
#

By the end of this lecture, you will be able to:

  • ๐Ÿ”’ Understand data encapsulation and information hiding principles
  • ๐Ÿ›ก๏ธ Master all four access modifiers in Java
  • ๐Ÿ—๏ธ Apply access control to protect class members
  • ๐Ÿ” Implement secure class design patterns
  • ๐ŸŽฏ Choose appropriate access levels for different scenarios
  • ๐Ÿ“ Practice with real-world encapsulation examples

Let's secure our code with access control! ๐Ÿ”’๐Ÿ›ก๏ธ

layout: center
#

What is Encapsulation?
#

graph TD
    A[Encapsulation] --> B[Data Hiding]
    A --> C[Access Control]
    A --> D[Security]
    
    B --> E[Private Variables]
    B --> F[Internal Implementation]
    
    C --> G[Public Methods]
    C --> H[Controlled Access]
    
    D --> I[Data Validation]
    D --> J[Unauthorized Access Prevention]
    
    style A fill:#e3f2fd
    style B fill:#e8f5e8
    style C fill:#fff3e0
    style D fill:#f3e5f5

๐Ÿ—๏ธ Encapsulation

  • โ€ข Bundling data and methods together
  • โ€ข Controlling access to internal details
  • โ€ข Protecting object state
  • โ€ข Enabling secure programming

๐Ÿ”’ Benefits

  • โ€ข Data security and integrity
  • โ€ข Code maintainability
  • โ€ข Flexible implementation changes
  • โ€ข Better error handling

layout: default
#

Access Modifiers Overview
#

๐Ÿ›ก๏ธ Four Access Levels
#

ModifierSymbolAccess Level
private๐Ÿ”’Within same class only
default๐Ÿ“ฆWithin same package
protected๐Ÿ Package + subclasses
public๐ŸŒAccessible everywhere

๐Ÿ“Š Visibility Scope
#

public class AccessExample {
    private int privateVar;      // ๐Ÿ”’ Class only
    int defaultVar;              // ๐Ÿ“ฆ Package
    protected int protectedVar;  // ๐Ÿ  Package + subclasses
    public int publicVar;        // ๐ŸŒ Everywhere
}

๐ŸŽฏ Access Control Matrix
#

Access LevelSame ClassSame PackageSubclassDifferent Package
privateโœ…โŒโŒโŒ
defaultโœ…โœ…โŒโŒ
protectedโœ…โœ…โœ…โŒ
publicโœ…โœ…โœ…โœ…
๐ŸŽฏ Key Principle: Provide the minimum access necessary for functionality!

layout: default
#

Private Access Modifier
#

๐Ÿ”’ Most Restrictive Access
#

  • Accessible only within the same class
  • Cannot be accessed from outside
  • Used for internal implementation details
  • Provides complete data hiding
  • Foundation of encapsulation

๐Ÿ“ Basic Private Example
#

public class BankAccount {
    private double balance;        // Hidden from outside
    private String accountNumber;  // Secret account details
    private boolean isActive;      // Internal state
    
    // Private helper method
    private boolean validateAmount(double amount) {
        return amount > 0 && amount <= balance;
    }
    
    // Public method to access private data
    public double getBalance() {
        return balance;
    }
}

๐Ÿšซ What Happens Without Private?
#

// Without encapsulation (BAD)
public class UnsafeBankAccount {
    public double balance;         // Anyone can modify!
    public String accountNumber;   // Exposed sensitive data
    
    public void withdraw(double amount) {
        balance -= amount;         // No validation!
    }
}

// Dangerous usage
UnsafeBankAccount account = new UnsafeBankAccount();
account.balance = 1000000;       // Illegal modification!
account.accountNumber = "123456"; // Security breach!

Problems:

  • No data validation
  • Security vulnerabilities
  • Inconsistent state possible
  • No control over modifications
โš ๏ธ Security Risk: Public data members expose internal implementation and create security holes!

layout: default
#

Implementing Data Encapsulation
#

๐Ÿ—๏ธ Complete Encapsulated Class
#

public class Student {
    // Private data members (hidden)
    private String name;
    private int rollNumber;
    private double marks;
    private boolean isActive;
    
    // Constructor for initialization
    public Student(String name, int rollNumber) {
        this.name = name;
        this.rollNumber = rollNumber;
        this.marks = 0.0;
        this.isActive = true;
    }
    
    // Getter methods (Accessors)
    public String getName() {
        return name;
    }
    
    public int getRollNumber() {
        return rollNumber;
    }
    
    public double getMarks() {
        return marks;
    }
    
    public boolean isActive() {
        return isActive;
    }
}
    // Setter methods (Mutators) with validation
    public void setName(String name) {
        if (name != null && name.trim().length() > 0) {
            this.name = name.trim();
        } else {
            System.out.println("Invalid name provided");
        }
    }
    
    public void setMarks(double marks) {
        if (marks >= 0 && marks <= 100) {
            this.marks = marks;
        } else {
            System.out.println("Marks must be between 0 and 100");
        }
    }
    
    public void setActive(boolean active) {
        this.isActive = active;
    }
    
    // Business logic methods
    public char getGrade() {
        if (marks >= 90) return 'A';
        else if (marks >= 80) return 'B';
        else if (marks >= 70) return 'C';
        else if (marks >= 60) return 'D';
        else return 'F';
    }
    
    public void displayInfo() {
        System.out.println("Student: " + name);
        System.out.println("Roll Number: " + rollNumber);
        System.out.println("Marks: " + marks);
        System.out.println("Grade: " + getGrade());
        System.out.println("Status: " + (isActive ? "Active" : "Inactive"));
    }
}

layout: default
#

Using Encapsulated Classes
#

๐ŸŽฏ Safe Usage Example
#

public class StudentDemo {
    public static void main(String[] args) {
        // Create student object
        Student student = new Student("Alice Johnson", 101);
        
        // Safe access through public methods
        System.out.println("Name: " + student.getName());
        System.out.println("Roll: " + student.getRollNumber());
        
        // Validated data modification
        student.setMarks(85.5);
        student.setName("Alice M. Johnson");
        
        // Display complete information
        student.displayInfo();
        
        // Attempt invalid operations
        student.setMarks(150);    // Will show error message
        student.setMarks(-10);    // Will show error message
        student.setName("");      // Will show error message
        
        // These would cause compilation errors:
        // student.name = "Hacker";      // Error: private field
        // student.rollNumber = 999;     // Error: private field
        // student.marks = 200;          // Error: private field
    }
}

๐Ÿ›ก๏ธ Benefits Demonstrated
#

Data Validation:

student.setMarks(150);  // Automatically validated
// Output: "Marks must be between 0 and 100"

Controlled Access:

// Can read but not directly modify
String name = student.getName();    // โœ… Allowed
// student.name = "New Name";       // โŒ Compilation error

Flexible Implementation:

// Internal implementation can change without affecting users
public double getMarks() {
    // Could add logging, caching, etc.
    logAccess("Marks accessed for " + name);
    return marks;
}

Data Integrity:

// Roll number cannot be changed after creation
// Only name and marks can be modified with validation
๐Ÿ† Result: Secure, maintainable, and robust code!

layout: default
#

Default (Package-Private) Access
#

๐Ÿ“ฆ Package-Level Access
#

  • No access modifier specified
  • Accessible within the same package
  • Hidden from other packages
  • Default access level in Java
  • Useful for package-internal functionality

๐Ÿ“ Package Structure Example
#

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

public class Student {
    String studentId;        // Package-private
    String name;             // Package-private
    int semester;            // Package-private
    
    // Package-private method
    void updateSemester(int newSemester) {
        this.semester = newSemester;
    }
    
    public void displayInfo() {
        System.out.println("Student: " + name);
        System.out.println("ID: " + studentId);
        System.out.println("Semester: " + semester);
    }
}

๐Ÿ—๏ธ Package Access Usage
#

// File: com/university/StudentManager.java
package com.university;  // Same package

public class StudentManager {
    public void processStudent() {
        Student student = new Student();
        
        // โœ… Can access package-private members
        student.studentId = "STU001";
        student.name = "Bob Smith";
        student.semester = 4;
        
        // โœ… Can call package-private methods
        student.updateSemester(5);
        
        student.displayInfo();
    }
}

// File: com/admin/AdminPanel.java
package com.admin;       // Different package
import com.university.Student;

public class AdminPanel {
    public void manageStudent() {
        Student student = new Student();
        
        // โŒ Cannot access package-private members
        // student.studentId = "ADM001";    // Compilation error
        // student.name = "Admin";          // Compilation error
        // student.updateSemester(1);       // Compilation error
        
        // โœ… Can only access public methods
        student.displayInfo();
    }
}

layout: default
#

Protected Access Modifier
#

๐Ÿ  Family-Level Access
#

  • Accessible in same package
  • Accessible to subclasses (inheritance)
  • Not accessible to unrelated classes
  • Enables controlled inheritance
  • Balance between private and public

๐Ÿงฌ Inheritance Hierarchy
#

// Parent class
public class Vehicle {
    protected String brand;           // Subclasses can access
    protected int maxSpeed;          // Protected for inheritance
    private String engineNumber;     // Only Vehicle class
    
    protected void startEngine() {   // Subclasses can override
        System.out.println("Engine started");
    }
    
    protected void displaySpecs() {
        System.out.println("Brand: " + brand);
        System.out.println("Max Speed: " + maxSpeed);
    }
}

๐Ÿš— Subclass Access
#

// Child class
public class Car extends Vehicle {
    private int numberOfDoors;
    
    public Car(String brand, int maxSpeed, int doors) {
        // โœ… Can access protected members from parent
        this.brand = brand;
        this.maxSpeed = maxSpeed;
        this.numberOfDoors = doors;
        
        // โŒ Cannot access private members
        // this.engineNumber = "ENG123";  // Compilation error
    }
    
    // โœ… Can override protected methods
    @Override
    protected void startEngine() {
        System.out.println("Car engine started with key");
        super.startEngine();  // Call parent method
    }
    
    public void showCarDetails() {
        // โœ… Using protected method from parent
        displaySpecs();
        System.out.println("Doors: " + numberOfDoors);
    }
}

// Usage example
public class VehicleDemo {
    public static void main(String[] args) {
        Car car = new Car("Toyota", 180, 4);
        car.showCarDetails();
        
        // โŒ Cannot access protected members directly
        // car.brand = "Honda";        // Compilation error
        // car.startEngine();          // Compilation error
    }
}

layout: default
#

Public Access Modifier
#

๐ŸŒ Universal Access
#

  • Accessible from anywhere
  • No access restrictions
  • Used for public APIs
  • Classes, methods, and variables
  • Maximum visibility

๐Ÿ“‹ Public Interface Design
#

public class Calculator {
    // Public constants
    public static final double PI = 3.14159;
    public static final double E = 2.71828;
    
    // Public methods (API)
    public double add(double a, double b) {
        return a + b;
    }
    
    public double subtract(double a, double b) {
        return a - b;
    }
    
    public double multiply(double a, double b) {
        return a * b;
    }
    
    public double divide(double a, double b) {
        if (b == 0) {
            throw new IllegalArgumentException("Division by zero");
        }
        return a / b;
    }
}

๐ŸŽฏ Global Usage
#

// Can be used from any package, any class
import com.utilities.Calculator;

public class MathApplication {
    public static void main(String[] args) {
        Calculator calc = new Calculator();
        
        // โœ… All public methods accessible
        double sum = calc.add(10, 5);
        double difference = calc.subtract(10, 5);
        double product = calc.multiply(10, 5);
        double quotient = calc.divide(10, 5);
        
        // โœ… Public constants accessible
        double circleArea = Calculator.PI * 5 * 5;
        
        System.out.println("Sum: " + sum);
        System.out.println("Difference: " + difference);
        System.out.println("Product: " + product);
        System.out.println("Quotient: " + quotient);
        System.out.println("Circle Area: " + circleArea);
    }
}

// Another class in different package
package com.games;
import com.utilities.Calculator;

public class GameScoring {
    private Calculator calc = new Calculator();
    
    public double calculateBonus(double base, double multiplier) {
        return calc.multiply(base, multiplier);  // โœ… Public access
    }
}

layout: default
#

Real-World Example: Bank Account System
#

๐Ÿฆ Secure Banking Implementation
#

public class BankAccount {
    // Private - Critical data protection
    private String accountNumber;
    private double balance;
    private String pinCode;
    
    // Protected - For specialized account types
    protected String accountType;
    protected double interestRate;
    
    // Package-private - Bank internal operations
    String branchCode;
    boolean isVerified;
    
    // Public - Customer interface
    public BankAccount(String accountNumber, String pinCode) {
        this.accountNumber = accountNumber;
        this.pinCode = pinCode;
        this.balance = 0.0;
        this.accountType = "SAVINGS";
        this.interestRate = 0.04;
        this.isVerified = false;
    }
    
    // Public methods for customer operations
    public boolean authenticate(String pin) {
        return this.pinCode.equals(pin);
    }
    
    public double getBalance(String pin) {
        if (authenticate(pin)) {
            return balance;
        } else {
            System.out.println("Authentication failed");
            return -1;
        }
    }
}
    public boolean deposit(double amount, String pin) {
        if (!authenticate(pin)) {
            System.out.println("Authentication failed");
            return false;
        }
        
        if (amount > 0) {
            balance += amount;
            System.out.println("Deposited: โ‚น" + amount);
            return true;
        } else {
            System.out.println("Invalid amount");
            return false;
        }
    }
    
    public boolean withdraw(double amount, String pin) {
        if (!authenticate(pin)) {
            System.out.println("Authentication failed");
            return false;
        }
        
        if (amount > 0 && amount <= balance) {
            balance -= amount;
            System.out.println("Withdrawn: โ‚น" + amount);
            return true;
        } else {
            System.out.println("Invalid amount or insufficient funds");
            return false;
        }
    }
    
    // Protected method for subclasses
    protected double calculateInterest() {
        return balance * interestRate / 12;  // Monthly interest
    }
    
    // Package-private for bank operations
    void setVerificationStatus(boolean verified) {
        this.isVerified = verified;
    }
}

layout: default
#

Specialized Account Types
#

๐Ÿ’ณ Savings Account (Inheritance)
#

public class SavingsAccount extends BankAccount {
    private double minimumBalance;
    
    public SavingsAccount(String accountNumber, String pinCode) {
        super(accountNumber, pinCode);
        this.minimumBalance = 1000.0;
        this.accountType = "SAVINGS";    // โœ… Protected access
        this.interestRate = 0.04;        // โœ… Protected access
    }
    
    @Override
    protected double calculateInterest() {
        // โœ… Can override protected method
        return super.calculateInterest() * 1.2;  // Bonus interest
    }
    
    @Override
    public boolean withdraw(double amount, String pin) {
        if (!authenticate(pin)) {
            return false;
        }
        
        // Check minimum balance constraint
        if (getBalance(pin) - amount >= minimumBalance) {
            return super.withdraw(amount, pin);
        } else {
            System.out.println("Cannot withdraw. Minimum balance required: โ‚น" + minimumBalance);
            return false;
        }
    }
    
    public double getMinimumBalance() {
        return minimumBalance;
    }
}

๐Ÿง Usage and Security Demonstration
#

public class BankingDemo {
    public static void main(String[] args) {
        SavingsAccount account = new SavingsAccount("SAV001", "1234");
        
        // โœ… Public interface usage
        account.deposit(5000, "1234");
        System.out.println("Balance: โ‚น" + account.getBalance("1234"));
        
        // โœ… Specialized savings account behavior
        account.withdraw(3500, "1234");  // Will check minimum balance
        
        // โœ… Account type specific method
        System.out.println("Minimum balance: โ‚น" + account.getMinimumBalance());
        
        // โŒ Security - These would cause compilation errors:
        // account.balance = 1000000;         // Private
        // account.pinCode = "0000";          // Private
        // account.accountNumber = "HACK";    // Private
        
        // โŒ These would also fail:
        // account.calculateInterest();       // Protected
        // account.setVerificationStatus(true); // Package-private
        
        // Authentication protection
        account.withdraw(1000, "wrong_pin");  // Will fail authentication
    }
}
๐Ÿ” Security Achieved:
  • โ€ข Critical data completely hidden
  • โ€ข All operations require authentication
  • โ€ข Business rules enforced automatically
  • โ€ข Inheritance enables specialization

layout: default
#

Access Modifier Best Practices
#

โœ… Design Guidelines
#

Start with Most Restrictive:

  • Begin with private by default
  • Only make public what’s absolutely necessary
  • Use protected for inheritance hierarchies
  • Use package-private for related classes

Data Members:

  • Almost always private
  • Use getters/setters for controlled access
  • Constants can be public static final

Methods:

  • Public for external interface
  • Private for internal helpers
  • Protected for overridable behavior

Classes:

  • Public for external use
  • Package-private for internal implementation

๐ŸŽฏ Common Patterns
#

public class WellDesignedClass {
    // Constants - public is acceptable
    public static final String VERSION = "1.0";
    
    // Critical data - always private
    private String sensitiveData;
    private double criticalValue;
    
    // Configuration - package-private for testing
    boolean debugMode;
    
    // Extensible behavior - protected
    protected void initialize() {
        // Subclasses can override
    }
    
    // Public API - minimal and focused
    public void performOperation() {
        if (validate()) {
            execute();
            logOperation();
        }
    }
    
    // Private helpers - internal implementation
    private boolean validate() {
        return sensitiveData != null;
    }
    
    private void execute() {
        // Core logic
    }
    
    private void logOperation() {
        // Logging implementation
    }
}
๐ŸŽฏ Remember: Good encapsulation leads to secure, maintainable, and flexible code!

layout: default
#

Hands-On Exercise: Employee Management System
#

๐Ÿ› ๏ธ Design Challenge
#

Requirements:

  1. Create an Employee class with proper encapsulation
  2. Include employee ID, name, salary, and department
  3. Implement validation for all data
  4. Create specialized Manager subclass
  5. Demonstrate all access levels appropriately
public class Employee {
    // TODO: Design with appropriate access modifiers
    // - Employee ID (read-only after creation)
    // - Name (changeable with validation)
    // - Salary (private, controlled access)
    // - Department (package access for HR)
    
    // TODO: Constructor with validation
    
    // TODO: Getters and setters with business rules
    
    // TODO: Protected method for salary calculation
    
    // TODO: Package method for HR operations
    
    // TODO: Public methods for external interface
}

๐ŸŽฏ Expected Implementation
#

public class Manager extends Employee {
    // TODO: Additional manager-specific features
    // - Team size
    // - Bonus calculation
    // - Override salary calculation
    
    // TODO: Use protected inheritance appropriately
}

public class EmployeeDemo {
    public static void main(String[] args) {
        // TODO: Demonstrate:
        // โœ… Valid operations
        // โŒ Security restrictions
        // ๐Ÿ”ง Proper encapsulation usage
    }
}

Success Criteria:

  • All data properly encapsulated
  • Validation in setters
  • Appropriate access levels used
  • Inheritance demonstrates protected usage
  • Security violations prevented
  • Clean public interface

layout: default
#

Common Access Modifier Mistakes
#

โŒ Making Everything Public

```java public class BadStudent { public String name; // No validation possible public int rollNumber; // Can be changed externally public double marks; // No business rules enforced } ``` Problem: No encapsulation, no data validation, security vulnerabilities

โŒ Inconsistent Access Patterns

```java public class InconsistentClass { private String name; public String getName() { return name; } // Good
public double salary;                       // Bad - should be private
private void setSalary(double s) { salary = s; }  // Bad - should be public

}

<strong>Problem:</strong> Confusing interface, breaks encapsulation principles
</div>

<div class="bg-yellow-50 p-4 rounded-lg">
<h4 class="font-bold text-yellow-700">โŒ Overusing Protected</h4>
```java
public class OverProtected {
    protected String internalId;      // Should probably be private
    protected void helperMethod() {} // Internal logic, should be private
}

Problem: Exposes implementation details unnecessarily to subclasses

โœ… Correct Access Control

```java public class WellEncapsulated { private String name; // Data hidden public String getName() { return name; } // Controlled read access public void setName(String name) { // Validated write access if (name != null && !name.trim().isEmpty()) { this.name = name.trim(); } } } ```

layout: center class: text-center
#

Summary
#

๐Ÿ“– What We Learned

  • โ€ข Encapsulation and data hiding principles
  • โ€ข Four access modifiers: private, default, protected, public
  • โ€ข Secure class design patterns
  • โ€ข Getters and setters implementation
  • โ€ข Real-world access control applications
  • โ€ข Best practices and common mistakes

๐ŸŽฏ Next Steps

  • โ€ข Understanding 'this', 'static', and 'final' keywords
  • โ€ข Advanced encapsulation techniques
  • โ€ข Constructor implementation
  • โ€ข Method and constructor overloading
  • โ€ข Object-oriented design patterns
Data security mastered! Your objects are now protected! ๐Ÿ”’๐Ÿ›ก๏ธ

layout: center class: text-center
#

Questions & Discussion
#

โ“
Any questions about access modifiers, encapsulation, or data security?
Next lecture: **Keywords - this, static, final**
Ready to explore powerful Java keywords! ๐Ÿ‘