Memra

Access control & packages

public/protected/private/package access, the package/import library unit, and the silent default.

The library unit: a package

A package is Java's unit of reuse and namespacing. The package statement is the *first* non-comment line of a source file and maps directly to a directory path: a class declared package com.greenhouse.events; must live in com/greenhouse/events/. Other code pulls it in with import com.greenhouse.events.Event; (one type) or import com.greenhouse.events.*; (all public types of that package, not sub-packages). Without an import you must use the fully-qualified name com.greenhouse.events.Event.

The four access levels

Java has four access levels for members (fields, methods, constructors), ordered most-open to most-closed:

- public — any code anywhere can access it. It is the deliberate, published interface of your class. - protected — the same package *and* subclasses (even in other packages). It says "this is for people extending me." - package-private (the *default* — no keyword) — only code in the same package. This is the level you get when you forget to write a modifier. - private — only the *enclosing class* itself. The implementation detail nobody outside touches.

A top-level class itself may be only public or package-private (default). There is no private or protected top-level class.

Worked example: a two-class package with mixed access

package bank;

public class Account {
    private double balance;          // hidden from everyone
    protected String owner;          // visible to subclasses + package
    double feeRate = 0.01;           // package-private (default)

    public void deposit(double amt) { balance += amt; }
    public double getBalance() { return balance; }
}
package bank;                        // SAME package as Account

class Auditor {
    void check(Account a) {
        System.out.println(a.getBalance());  // OK: public
        System.out.println(a.feeRate);       // OK: same package sees default
        // System.out.println(a.balance);    // COMPILE ERROR: private
    }
}

Auditor reaches feeRate only because it shares the bank package. Move Auditor to another package and that line stops compiling — but getBalance() keeps working because it is public. The rule of thumb: expose as little as possible. Make fields private and reach them through methods so you can change the internals later without breaking callers.

NORMAL ~/memra/learn/comp-308/access-control-and-packages utf-8 LF