Hiprup

What are the access modifiers in Java, and what is the scope of each?

Java provides four access modifiers that control the visibility of classes, fields, methods, and constructors: private, default (package-private), protected, and public. Ordered from most to least restrictive, they let you expose only what other code genuinely needs — the foundation of encapsulation.

Note that a top-level class can only be public or default, while members and constructors can use all four levels.

  • private — accessible only inside the declaring class; even subclasses cannot see it. Used to hide internal fields and helper methods.

  • default (no keyword) — accessible to every class in the same package only; often called package-private.

  • protected — accessible throughout the same package and in subclasses in other packages via inheritance.

  • public — accessible from anywhere in the application, across all packages.

  • Automation practice — in a Selenium Page Object class, locators such as By or WebElement fields are kept private, action methods like login() are public so TestNG classes in other packages can call them, and shared members like WebDriver in a base class are usually protected.

Key terms: private, default (package-private), protected, public, encapsulation, package, inheritance, Page Object Model

class Vehicle {
    private String engineNumber = "EN-123"; // only inside Vehicle
    String model = "Sedan";                 // default: same package only
    protected int wheels = 4;               // package + subclasses
    public String brand = "Tesla";          // everywhere

    private void startEngine() {
        System.out.println("Engine started: " + engineNumber);
    }

    public void drive() {
        startEngine(); // private method is fine inside its own class
        System.out.println(brand + " " + model + " on " + wheels + " wheels");
    }
}

class Car extends Vehicle {
    public void showAccess() {
        System.out.println(brand);   // public: OK
        System.out.println(model);   // default: OK (same package)
        System.out.println(wheels);  // protected: OK via inheritance
        // System.out.println(engineNumber); // COMPILE ERROR: private in Vehicle
    }
}

public class AccessModifierDemo {
    public static void main(String[] args) {
        Car car = new Car();
        car.drive();
        // Output: Engine started: EN-123
        // Output: Tesla Sedan on 4 wheels
        car.showAccess();
        // Output: Tesla
        // Output: Sedan
        // Output: 4
    }
}

Vehicle declares one field at each access level, and Car — a subclass in the same package — shows which of them it can legally read: public, default, and protected all work, while uncommenting the engineNumber line fails to compile with "engineNumber has private access in Vehicle". The private startEngine() method still runs because private members are freely usable inside their own class, which is exactly how Page Objects hide locators while exposing public action methods.

Save the file as AccessModifierDemo.java since it must match the public class name; moving Car to a different package would additionally break access to the default field model, leaving only public and protected (via inheritance) visible.

Recite the order from most to least restrictive (private, default, protected, public) and add that top-level classes can only be public or default — that detail signals real preparation. Expect follow-ups like the difference between protected and default, and why locators are private in Page Objects.

The classic mistake is saying protected means "subclasses only" — it also covers the entire package.