The protected modifier provides a middle level of access between private and public. It is especially useful when a class wants to keep a member away from general public access while still allowing related classes, particularly subclasses, to use it.
A useful way to think about protected is to imagine a family workshop. The workshop is not open to everyone, but members of the family can use certain tools. Java's protected access follows a similar idea: access is available within the same package and also to subclasses under specific rules.
Why Does the protected Modifier Exist?
Inheritance is one of the main reasons Java provides protected access. A parent class may contain functionality that is useful to its subclasses but should not become part of the unrestricted public interface.
For example, a Vehicle class might provide a protected method that subclasses such as Car and Bike can use internally.
protected members are accessible within the same package and are also accessible to subclasses, including subclasses in another package subject to Java's access rules.
Basic Syntax
protected dataType variableName; protected returnType methodName() { // method body }
The protected keyword can be used with fields, methods, constructors, and nested classes. A top-level class cannot be declared protected.
protected Field Example
class Employee { protected String department = "IT"; } class Developer extends Employee { void displayDepartment() { System.out.println(department); } }
Developer extends Employee, so it can directly access the protected department member inherited from Employee.
protected Method Example
Protected methods are particularly useful when a parent class provides a reusable operation for subclasses.
class Vehicle { protected void startEngine() { System.out.println("Engine started"); } } class Car extends Vehicle { public void drive() { startEngine(); System.out.println("Car is moving"); } }
The Car class can use startEngine() because it inherits from Vehicle. External classes that are not related through inheritance do not receive unrestricted access to the protected member.
protected Within the Same Package
An important detail that beginners often miss is that protected members are accessible to other classes in the same package, even when those classes are not subclasses.
package company; public class Employee { protected String department = "Engineering"; }
Another class in the same package can access the protected member.
package company; public class Manager { public void showDepartment() { Employee employee = new Employee(); System.out.println(employee.department); } }
This is different from private access. A private member would not be directly accessible from Manager even though both classes belong to the same package.
Same package access is one of the easiest ways to remember protected: package members can access it, and subclasses can access it under inheritance rules.
protected Across Different Packages
The more interesting case occurs when a subclass belongs to a different package. A subclass can access inherited protected members, but Java applies an important restriction.
package company; public class Employee { protected String role = "Developer"; }
A subclass in another package can access the protected member through inheritance.
package application; import company.Employee; public class Developer extends Employee { public void showRole() { System.out.println(role); } }
Here, Developer is a subclass of Employee, so it can access the inherited protected member.
A Subtle Cross-Package Rule
When a subclass is in a different package, protected access is not equivalent to public access. The subclass can access the inherited protected member through the subclass relationship, but unrelated external code cannot simply access it through any Employee object.
This distinction becomes important in interviews and when designing inheritance-based APIs.
package application; import company.Employee; public class Developer extends Employee { public void showRole() { Employee employee = new Employee(); // Direct access through an unrelated Employee reference // is not permitted across the package boundary. } }
The protected rule is therefore best understood as a combination of package access and inheritance access rather than simply “accessible to subclasses everywhere.”
protected and Inheritance
Protected access becomes especially useful when a parent class intentionally provides extension points for child classes.
class Report { protected void prepareData() { System.out.println("Preparing report data"); } public void generate() { prepareData(); System.out.println("Generating report"); } } class SalesReport extends Report { public void generateSalesReport() { prepareData(); System.out.println("Generating sales report"); } }
The protected method allows the subclass to reuse a piece of the parent's implementation without making that implementation detail publicly accessible to every class.
protected Constructor
Constructors can also be protected. This can be useful when a class should allow construction from subclasses or from classes in the same package but should not provide unrestricted public construction.
class Vehicle { protected Vehicle() { System.out.println("Vehicle created"); } } class Car extends Vehicle { public Car() { super(); } }
The Car constructor can invoke the protected parent constructor using super().
protected vs private
| Feature | private | protected |
|---|---|---|
| Same class | Allowed | Allowed |
| Same package | Not directly accessible | Allowed |
| Subclass | Not directly accessible | Allowed under protected access rules |
| Different package, unrelated class | Not allowed | Not allowed |
| Typical purpose | Hide implementation details | Support package-level use and inheritance |
protected vs public
| Feature | protected | public |
|---|---|---|
| Same class | Allowed | Allowed |
| Same package | Allowed | Allowed |
| Subclass in another package | Allowed under protected rules | Allowed |
| Unrelated class in another package | Not allowed | Allowed |
| Typical purpose | Controlled extension and package-level access | Public API |
When Should You Use protected?
Use protected when a member is intentionally part of the implementation or extension model of a class and needs to be available to subclasses or classes within the same package.
For example, framework and library designers sometimes use protected methods as extension points. A subclass can override or call these methods while ordinary users of the class interact through public methods.
Do not choose protected simply because it feels like a convenient middle option. Protected members increase the surface area that subclasses and package classes can depend on.
Common Beginner Mistakes
- Thinking protected means “subclasses only.” Same-package classes can also access protected members.
- Assuming protected is equivalent to public for subclasses in different packages.
- Trying to access a protected member through an unrelated object across a package boundary.
- Using protected fields when a controlled method would provide better encapsulation.
- Declaring a top-level class protected, which Java does not allow.
Best Practices
- Use protected deliberately when designing inheritance-based behaviour.
- Prefer protected methods over protected mutable fields when subclasses need controlled behaviour.
- Keep members private when subclasses do not genuinely need direct access.
- Document protected extension points in reusable libraries and frameworks.
- Avoid exposing protected members simply to bypass encapsulation problems.
Interview Insights
A frequently asked interview question is: “Is protected accessible outside the package?” The precise answer is yes, but only in the context of inheritance. A subclass in another package can access inherited protected members according to Java's protected access rules.
Another common question is: “Can a non-subclass in the same package access a protected member?” Yes. Same-package classes can access protected members even when inheritance is not involved.
The easiest interview formula is: protected gives access to the declaring class, same-package classes, and subclasses, with additional restrictions when the subclass is in another package.
Quick Revision
| Concept | Key Point |
|---|---|
| protected field | Can be accessed within the same package and by subclasses under Java's protected rules. |
| protected method | Useful for behaviour intended for package classes or subclasses. |
| Same package | Protected access is available to classes in the same package. |
| Different package | Subclass access is possible, but it is not unrestricted public access. |
| Top-level class | Cannot be declared protected. |
| Design purpose | Useful for controlled extension and package-level collaboration. |
The protected modifier occupies an important middle ground in Java's access-control system. It gives classes in the same package useful access while also supporting inheritance across package boundaries under specific rules. Once you understand that distinction, protected becomes much easier to reason about—and you can make better decisions about when inheritance should expose functionality and when a member should remain completely private.
