CACS204 Object Oriented Programming in Java

Object Oriented Programming in JavaUnit 77 min read

Packages, Access Modifiers & Java Modularity

Unit 7 of Object Oriented Programming in Java covers how to organize Java code into reusable packages, the four access modifiers (public, protected, default, private), their scope rules, and how to use them with classes, methods, and fields. Learn package declaration syntax, import statements, and how access control en

Core Concepts

1. Packages: Java’s Modular Organization

Packages group related classes/interfaces into namespaces to avoid naming conflicts and improve code reuse. They act like folders in a filesystem.

How Packages Work

  • Declaration: Every .java file must start with a package statement (e.g., package com.esewa.payment;).
  • Directory Structure: The package name maps to the filesystem path (e.g., com/esewa/payment/).
  • Importing: Use import to access classes from other packages (e.g., import java.util.*).

Example: eSewa’s Payment System

// File: com/esewa/payment/Transaction.java
package com.esewa.payment;

public class Transaction {
    public void processPayment(double amount) {
        System.out.println("Processing NPR " + amount + " via eSewa");
    }
}
// File: Main.java (in default package)
import com.esewa.payment.Transaction;

public class Main {
    public static void main(String[] args) {
        Transaction txn = new Transaction();
        txn.processPayment(500.00); // Output: Processing NPR 500.0 via eSewa
    }
}

Figure: Package Hierarchy for eSewa

```mermaid
classDiagram
    class com {
        +esewa
    }
    class com.esewa {
        +payment
    }
    class com.esewa.payment {
        Transaction
    }
    com.esewa.payment --> Transaction : contains

2. Access Modifiers: Controlling Visibility

Access modifiers restrict how classes, methods, and fields can be accessed. They enforce encapsulation (hiding implementation details).

Modifier Class Package Subclass World
public ✅ ✅ ✅ ✅
protected ✅ ✅ ✅ ❌
default* ✅ ✅ ❌ ❌
private ✅ ❌ ❌ ❌

*No keyword needed (package-private).

Real-World Use in Ncell’s Billing System

package com.ncell.billing;

public class BillGenerator {
    private double baseRate;       // Only accessible within BillGenerator
    protected String customerId;   // Accessible to subclasses (e.g., PremiumBillGenerator)
    public double calculateBill() { // Public API for clients
        return baseRate * 30;      // 30-day billing cycle
    }
}

Figure: Access Modifier Scope

```mermaid
stateDiagram-v2
    [*] --> World: public
    [*] --> Package: protected
    [*] --> Subclass: protected
    [*] --> Class: private

3. Subtopics Breakdown

a) Package Naming Conventions

  • Use reverse domain names (e.g., com.esewa, org.pokharauniversity).
  • Avoid top-level packages like java, javax, or sun.

b) Import Statements

  • Static Import: Import static members directly (e.g., import static java.lang.Math.PI;).
  • Wildcard Import: import java.util.* (use sparingly to avoid naming conflicts).

c) Access Modifier Rules

  1. Class-Level Modifiers:
    • Only public or default (no private/protected for classes).
  2. Method/Field Modifiers:
    • private: Hide implementation (e.g., private double calculateTax()).
    • protected: Allow subclass access (e.g., protected void validateCustomer()).
  3. Constructor Access:
    • Controls object creation (e.g., private BankAccount() for singleton pattern).

d) Inheritance and Access Modifiers

  • A subclass can access protected and public members of its parent.
  • Example: Daraz’s Order class (protected fields for OrderProcessor subclass).
package com.daraz.order;

public class Order {
    protected String orderId; // Accessible to OrderProcessor
    private double total;     // Hidden from subclasses
}

Worked Example: Kathmandu Traffic Route Planner

Scenario: Simulate a traffic system where TrafficLight and Vehicle classes interact.

// File: com/kathmandu/traffic/TrafficLight.java
package com.kathmandu.traffic;

public class TrafficLight {
    private String location; // e.g., "Thapathali"
    protected boolean isRed;

    public void changeLight() {
        isRed = !isRed; // Toggle state
    }

    public boolean getStatus() {
        return isRed;
    }
}
// File: com/kathmandu/vehicle/Vehicle.java
package com.kathmandu.vehicle;

import com.kathmandu.traffic.TrafficLight;

public class Vehicle {
    private String licensePlate;
    protected TrafficLight currentLight;

    public void move() {
        if (currentLight.getStatus()) { // Access protected method
            System.out.println("Stopping at " + currentLight.location);
        } else {
            System.out.println("Moving forward!");
        }
    }
}

Figure: State After changeLight() Call

```mermaid
stateDiagram-v2
    TrafficLight: isRed = true
    Vehicle: currentLight --> TrafficLight
    Vehicle: move() --> "Stopping at Thapathali"

Common Pitfalls and Best Practices

  1. Circular Dependencies:

    • Avoid PackageA importing PackageB which imports PackageA.
    • Fix: Restructure into a common super-package.
  2. Overusing public:

    • Minimize public members to reduce coupling (e.g., expose only getTotal() instead of total).
  3. Default Package:

    • Avoid it for production code (leads to tight coupling).
  4. Access Modifiers in Interfaces:

    • All methods are public by default; fields are public static final.

In the Real World

  1. eSewa’s Transaction Module

    • Package: com.esewa.payment
    • Access Control: private fields for amount and transactionId; public methods like processPayment().
    • Why? Prevents external classes from directly modifying sensitive data.
  2. Ncell’s Billing System

    • Package: com.ncell.billing
    • Protected Methods: validateCustomer() for subclasses like PremiumBillGenerator.
    • Why? Allows custom billing logic while enforcing validation rules.
  3. Daraz’s Order Processing

    • Package: com.daraz.order
    • Default Access: OrderStatus enum accessible only within the package.
    • Why? Hides internal status codes from external APIs.

Exam Tip

  1. Package Questions:

    • Always show the directory structure and package declaration in code.
    • Example: For a com.university.grade package, draw:
      com/
      └── university/
          └── grade/
              └── GradeCalculator.java
      
  2. Access Modifier Tricks:

    • Common Exam Question: "Why can’t Main access private field x in ClassA?" Answer: Private members are only accessible within the same class. Use getters/setters for controlled access.
  3. Code Tracing:

    • For questions like "What happens when B extends A and A has a protected method?", trace:
      • Can B call A's protected method? Yes.
      • Can a class in another package call it? No (unless it’s public).
  4. GUI + Packages:

    • If asked to create a GUI form (e.g., even/odd checker), structure it as:
      package com.tu.exam.gui;
      import javax.swing.*;
      
    • Use default access for helper classes (e.g., EvenOddCheckerHelper).

Visual Summary

```mermaid
mindmap
  root((Packages & Access Modifiers))
    Concepts
      Packages: Namespaces
      Access Modifiers: public/protected/default/private
    Real-World
      eSewa: com.esewa.payment
      Ncell: com.ncell.billing
      Daraz: com.daraz.order
    Exam Tips
      Show directory structure
      Trace access rules
      GUI + package structure

Based on the TU BCA syllabus for Object Oriented Programming in Java (CACS204), unit 7.

Discussion

Loading…