Access modifiers in Java are the keywords private, protected and public, plus the default (package-private) level you get when you write none. They decide which classes can see a class, method, variable or constructor. The super keyword lets a child class use its parent's variables, methods and constructors. This page explains both with examples from Selenium frameworks. Looking for every reserved word instead? See the complete list of Java keywords.

What Is an Access Modifier?

Access modifiers (also called access specifiers) define the visibility and accessibility of classes, methods, variables, and constructors in Java.

They determine who can access a particular class or member, helping enforce encapsulation, improve security, and organize code.

Java provides four access modifiers:

  • private
  • default (package-private)
  • protected
  • public

Advertisement

Why Are Access Modifiers Important?

Access modifiers help:

  • Protect sensitive data.
  • Support encapsulation.
  • Improve code organization.
  • Prevent unauthorized access.
  • Promote code reusability.

Real-Life Example

Think of your house.

  • Private → Only you can enter your bedroom.
  • Protected → Family members can enter.
  • Default → Society members can enter your apartment building.
  • Public → Anyone can enter a public garden.

The Four Access Modifiers

Private

private is the most restrictive access modifier.

Private members can be accessed only within the same class.

Note: Classes and interfaces cannot be declared as private.

Best Use Cases

Example

class Employee {

    private String password;          // hidden from other classes; set via constructor or config
}

Default (Package-Private)

When no access modifier is specified, Java uses the default (package-private) access level.

Default members are accessible only within the same package.

Example

class Employee {

    String name = "John";
}

Protected

protected members are accessible:

  • Within the same package.
  • By subclasses in other packages.

Example

class Animal {

    protected void eat() {

        System.out.println("Eating");
    }
}

Public

public provides the widest level of access.

Public members can be accessed from any class in any package.

Example

public class Employee {

    public void display() {

        System.out.println("Employee");
    }
}

Access Modifier Comparison

Access Modifier Same Class Same Package Subclass (Different Package) Other Packages
private ✅ ❌ ❌ ❌
default ✅ ✅ ❌ ❌
protected ✅ ✅ ✅ ❌
public ✅ ✅ ✅ ✅

Why It Matters in Real Projects

Framework developers use access modifiers to:

  • Hide implementation details.
  • Secure business logic.
  • Prevent misuse of internal methods.
  • Improve maintainability.

Real-Time Testing Example

In Selenium Page Object Model (POM):

  • Web element locators are usually private.
  • Test methods are public.
  • Helper methods are often protected or package-private (default).

This improves encapsulation and prevents accidental access.


When Is the super Keyword Used?

The super keyword refers to the immediate parent class.

It is commonly used to:

  1. Access a parent class variable.
  2. Call a parent class method.
  3. Invoke a parent class constructor.

1. Accessing a Parent Class Variable

When parent and child classes have variables with the same name.

Example

class Animal {

    String color = "White";
}

class Dog extends Animal {

    String color = "Black";

    void printColor() {

        System.out.println(color);
        System.out.println(super.color);
    }
}

Output

Black
White

2. Calling a Parent Class Method

Used when a child class overrides a parent method.

Example

class Animal {

    void eat() {

        System.out.println("Eating...");
    }
}

class Dog extends Animal {

    void eat() {

        System.out.println("Eating bread...");
    }

    void bark() {

        System.out.println("Barking...");
    }

    void work() {

        super.eat();

        bark();
    }
}

3. Calling a Parent Class Constructor

Use super() to invoke the parent constructor.

Example

class Animal {

    Animal() {

        System.out.println("Animal is created");
    }
}

class Dog extends Animal {

    Dog() {

        super();

        System.out.println("Dog is created");
    }
}

Output

Animal is created
Dog is created

Real-Life Example

Imagine you and your father have the same name.

If someone calls that name, you clarify whether they mean you or your father.

Similarly, Java uses super to refer to the parent class.


Real-Time Testing Example

In Selenium Page Object frameworks, constructors commonly use:

super(driver);

This passes the WebDriver instance from the base page class to child page classes.


Purpose of break in a switch Statement

The break statement terminates the execution of a particular case.

Without break, Java continues executing the next cases.

This behavior is called fall-through.


Example

switch (value) {

    case 1:
        System.out.println("One");
        break;

    case 2:
        System.out.println("Two");

    case 3:
        System.out.println("Three");
        break;
}

If value is 2, the output will be:

Two
Three

Because there is no break after case 2.


Why Use break?

The break statement:

  • Stops execution of the current case.
  • Prevents accidental execution of subsequent cases.
  • Improves code clarity.

Default Constructor After Defining an Explicit Constructor

Java automatically creates a default (no-argument) constructor only if no constructor is defined in the class.

Once you create any constructor, Java stops generating the default constructor.


Example

class Student {

    Student(String name) {

    }
}

This class has no default constructor.

Trying to create an object like this:

Student s = new Student();

Results in a compile-time error.


How to Add Both Constructors

If you need both constructors, define them manually.

class Student {

    Student() {

    }

    Student(String name) {

    }
}

Why Does Java Work This Way?

Java assumes that once you define a constructor, you want complete control over object creation.


Real-Life Example

Imagine bringing your own lunch to work.

Since you already have food, the office cafeteria won't automatically give you a free lunch.

If you want both, you must explicitly request it.


Real-Time Testing Example

In Selenium Page Object Model:

LoginPage(WebDriver driver)

is commonly used.

If a framework uses reflection to instantiate the class with a no-argument constructor, you must explicitly add one.


Quick Summary

  • No constructor defined → Java creates a default constructor.
  • Any constructor defined → Java does not generate a default constructor.
  • If you need a no-argument constructor, define it explicitly.

Can You Override a Method by Changing Only the Return Type?

No.

Changing only the return type does not constitute method overriding.

The method signature consists of:

  • Method name
  • Parameter list

The return type is not part of the method signature.


Rules for Method Overriding

To override a method:

  • Method name must be the same.
  • Parameters must be identical.
  • Return type must be the same or covariant (a subtype of the original return type).

Incorrect Example

class Parent {

    int display() {

        return 10;
    }
}

class Child extends Parent {

    String display() {

        return "Hello";
    }
}

This produces a compile-time error because only the return type has changed.


Correct Example

class Parent {

    Number getValue() {

        return 100;
    }
}

class Child extends Parent {

    Integer getValue() {

        return 100;
    }
}

Here, Integer is a subtype of Number, so this is valid covariant return type overriding.


Why Is This Important?

This rule ensures consistency in inheritance and prevents ambiguity when overriding methods in frameworks and APIs.


Try It: super, Constructors, Overriding and switch in One Program

public class Demo {
    static class BasePage {
        protected final String driver;
        BasePage(String driver) {                         // no default constructor
            this.driver = driver;
            System.out.println("1. BasePage constructor: driver = " + driver);
        }
        Object title() { return "Base title"; }
        void open() { System.out.println("   BasePage.open()"); }
    }

    static class LoginPage extends BasePage {
        LoginPage(String driver) {
            super(driver);                                // must be the first statement
            System.out.println("2. LoginPage constructor");
        }
        @Override
        String title() { return "Login"; }               // covariant return: String is an Object
        @Override
        void open() {
            super.open();                                 // reuse the parent's behaviour
            System.out.println("   LoginPage.open() adds its own checks");
        }
    }

    public static void main(String[] args) {
        BasePage page = new LoginPage("chrome");
        System.out.println("title() → " + page.title());
        page.open();

        int day = 2;
        switch (day) {                                    // classic switch: falls through without break
            case 1: System.out.println("One"); break;
            case 2: System.out.println("Two");
            case 3: System.out.println("Three"); break;
        }
        String label = switch (day) {                     // Java 14+ switch expression: no fall-through
            case 1 -> "One";
            case 2 -> "Two";
            default -> "Other";
        };
        System.out.println("switch expression → " + label);
    }
}

Output (compiled and run with Java 21):

1. BasePage constructor: driver = chrome
2. LoginPage constructor
title() → Login
   BasePage.open()
   LoginPage.open() adds its own checks
Two
Three
switch expression → Two
  • The parent constructor ran first — super(driver) must be the first statement, exactly like super(driver) in a Page Object.
  • Calling through a BasePage reference still ran LoginPage's methods — runtime polymorphism.
  • super.open() reused the parent's behavior instead of copying it.
  • The classic switch fell through from case 2 into case 3 because of the missing break; the Java 14+ arrow form can't fall through.

What the compiler says when you break the rules

MistakeReal javac error
Overriding int display() with String display()display() in Child cannot override display() in Parent — return type String is not compatible with int
Overriding a public method without publicshow() in C cannot override show() in P — attempting to assign weaker access privileges; was public
new Student() when only Student(String name) existsconstructor Student in class Student cannot be applied to given types; required: String, found: no arguments

The last one is the "default constructor" rule in action: Java only adds a no-argument constructor when you write no constructor at all. Always add @Override when overriding — if you misspell the method or change its signature, the compiler tells you instead of silently creating a new method. Step through the constructor chain and method calls in the Java Code Visualizer. How these keywords shape a framework: OOP Concepts in Your Framework.

From Real Projects

Java has been the language of every automation framework I've worked with — Selenium, TestNG, POM classes and Apache POI for Excel data. Interviews for automation roles regularly include basic programs like this one, often followed by a question on OOP concepts. Practice writing it by hand and explaining how you'd test it. On Canolog, the many forms and screens across sales, inventory, finance and service are where keeping page details in POM classes and reusable steps in a business library paid off. Be ready to explain overloading versus overriding with a short example — it's a favorite interview question.


📚 Official documentation: dev.java: Learn Java (Oracle) · Java 21 API documentation

Java Keywords at a Glance

The keywords on this page — public, protected, private, super, this, break — are part of Java's 51 reserved keywords (Java 9+). Reserved keywords can't be used as names for variables, methods or classes; true, false and null are literals, and var, record and yield are contextual keywords.

👉 See every keyword with its meaning, grouped and verified with the Java 21 compiler: Java Keywords: Complete List of All 51 Reserved Keywords.

Access Modifiers vs Non-Access Modifiers

Java has two families of modifier keywords. Access modifiers control who can use a member; non-access modifiers change how it behaves. A declaration can combine one access modifier with several non-access modifiers, as in public static final.

ModifierFamilyWhat it doesWhere you see it in a framework
privateAccessVisible only inside the same classLocator fields in a page object
(default)AccessVisible inside the same packageHelper classes used by one package
protectedAccessSame package plus subclassesThe driver field in BaseTest
publicAccessVisible everywhereTest methods and page actions
staticNon-accessBelongs to the class, not to each objectConfigReader.get("baseUrl")
finalNon-accessVariable can't be reassigned, method can't be overridden, class can't be extendedTimeout constants
abstractNon-accessMethod has no body; class can't be instantiatedAn abstract BasePage
synchronizedNon-accessOnly one thread runs the method at a timeA shared report writer in parallel runs

Two rules interviewers like to check:

  • A top-level class can only be public or default. private and protected are allowed only on nested classes.
  • An overriding method can't reduce visibility. A public method in the parent can't become protected in the child, but a protected one can become public.

FAQs

1. What Is an Access Modifier in Java?

An access modifier is a keyword that controls the visibility of classes, methods, variables, and constructors.

Java provides four access modifiers:

  • private
  • default
  • protected
  • public

2. What Is the Difference Between protected and default?

  • default (package-private) allows access only within the same package.
  • protected allows access within the same package and by subclasses in different packages.

3. When Is the super Keyword Used?

The super keyword is used to refer to the immediate parent class.

It can:

  • Access parent variables.
  • Call parent methods.
  • Invoke parent constructors.

4. What Is the Purpose of break in a switch Statement?

The break statement terminates the current case and prevents execution from falling through to the next case.


5. Does Java Provide a Default Constructor If You Define Your Own?

No.

Once any constructor is explicitly defined, Java no longer generates the default no-argument constructor.

If you need one, you must define it manually.


6. Can You Override a Method by Changing Only the Return Type?

No.

Method overriding requires the same method name and parameter list.

The return type must be the same or a covariant subtype. Changing only the return type results in a compile-time error.


7. What is the difference between this and super in Java?

this refers to the current object; super refers to the parent-class part of it. this() calls another constructor of the same class and super() calls the parent constructor. Both must be the first statement in a constructor, so one constructor can't call both.


8. Is default an access modifier keyword in Java?

No. There's no keyword for default (package-private) access; you get it by writing no modifier at all. The default keyword exists, but it's used in switch statements and for default methods in interfaces.


9. Can a top-level class be private or protected in Java?

No. A top-level class can only be public or package-private (no modifier). Only nested classes can be private or protected; the compiler rejects anything else.