Access Modifiers in Java - Quiz

Total: 5 questions

1. 

How many access modifiers and how many access levels does Java have?

Java has three access modifierspublic, protected and private — but four access levels. The fourth one, package-private (also called default access), has no keyword of its own: you get it when no modifier is written at all.

Who can see a member at each level:

  • public — any code that can see the class itself;
  • protected — the whole package, plus subclasses in other packages (through a reference of the subclass type);
  • package-private — only code in the same package;
  • private — only the body of the enclosing top-level class, including its nested classes.

The levels form a strict ordering from the most restrictive to the least: private → package-private → protectedpublic. Since Java 9 the module system (JPMS) adds an outer check on top of them: a public class stays invisible to other modules unless its package is exported with an exports directive.

2. 

What does the protected modifier give access to, and why does the call other.protectedAccessMethod() not compile inside Child?

package oop.p2;

import oop.p1.Parent;

public class Child extends Parent {
    public void compare(Parent other, Child sibling) {
        this.protectedAccessMethod();
        super.protectedAccessMethod();
        sibling.protectedAccessMethod();
        other.protectedAccessMethod();
    }
}

protected does two things at once: it opens the member to every class in the same package, exactly like package-private, and in addition to subclasses in other packages. So it is strictly wider than package-private, and the popular summary "protected is for subclasses" is incomplete: AccessClass placed next to Parent in oop.p1 reaches protectedAccessMethod() with no inheritance at all.

The last line does not compile because of the extra rule in the Java Language Specification (6.6.2.1): from a subclass in another package a protected member may be accessed only through an expression whose type is that subclass or a subtype of it. this, super and sibling are of type Child, so those three calls are fine; other is declared as Parent, so the compiler rejects it.

The intent: a subclass is trusted with its own inherited part of the object, not with every object of the parent type in the system.

3. 

Which access levels can a top-level class have in Java?

Only two of the four: public and package-private. The modifiers private and protected cannot be applied to a top-level class — the compiler rejects them. A nested class, on the other hand, accepts all four levels, because it is a member of its enclosing class.

If the class itself is invisible, nothing inside it is reachable, including its public members. An attempt to use the package-private class HotBeverage from another package fails already on the import line:

package oop.p1;

class HotBeverage {
}
package oop.p2;

// import oop.p1.HotBeverage; // Compile error: the class is not public

public class Tea {
    // extends HotBeverage - impossible from another package
}

One more rule, about files: a public class must be the only public top-level type in its file, and the file name must match the class name. Any number of package-private classes may sit next to it in the same file — but they are independent top-level classes and cannot see each other's private members:

// file Beverage.java
public class Beverage {
}

class HotBeverage {
}

class ColdBeverage {
}
4. 

Can an overriding method narrow the access level of the method it overrides?

No. When overriding, the access level may be kept or widened, never narrowed: package-private can be promoted to protected or public, and protected to public. An attempt to narrow it produces the compile error "attempting to assign weaker access privileges".

package oop.p1;

public class Child extends Parent {
    @Override
    public void hook() { // OK: protected widened to public
    }

    // @Override
    // void hook() {} // Error: attempting to assign weaker access privileges
}

The reason is the Liskov substitution principle: code holding a variable of type Parent must be able to call hook() whatever concrete subclass is plugged in.

A private method is a separate story — it is not inherited and therefore cannot be overridden at all. A method with the same signature in a subclass is simply a new, unrelated method, and putting @Override on it is a compile error.

5. 

Which access modifiers do interface members have in Java?

Interfaces play by their own rules:

  • abstract methods are implicitly public abstract, and fields are implicitly public static final;
  • writing public on an interface method is legal but redundant — most style guides treat it as noise. Omitting it does not make the method package-private: it is public either way;
  • since Java 8 an interface may declare default and static methods with a body. The default keyword here is about a default implementation, not about an access level;
  • since Java 9 an interface may declare private methods, used to factor shared code out of default methods.

So the only access level you can really choose inside an interface is private for a helper method — everything else that is part of the contract is public.

Page 1 of 1