Which access modifier makes variables and methods visible only in the class where they are declared?

Get full access to Learning Java, 4th Edition and 60K+ other titles, with free 10-day trial of O'Reilly.

There's also live online events, interactive content, certification prep materials, and more.

One of the most important aspects of object-oriented design is data hiding, or encapsulation. By treating an object in some respects as a “black box” and ignoring the details of its implementation, we can write more resilient, simpler code with components that can be easily reused.

By default, the variables and methods of a class are accessible to members of the class itself and to other classes in the same package. To borrow from C++ terminology, classes in the same package are friendly. We’ll call this the default level of visibility. As you’ll see as we go on, the default visibility lies in the middle of the range of restrictiveness that can be specified.

The modifiers public and private, on the other hand, define the extremes. As we mentioned earlier, methods and variables declared as private are accessible only within their class. At the other end of the spectrum, members declared as public are accessible from any class in any package, provided the class itself can be seen. (The class that contains the methods must also be public to be seen outside of its package, as we discussed previously.) The public members of a class should define its most general functionality—what the black box is supposed to do.

Figure 6-7 illustrates the four simplest levels of visibility, continuing the example from the previous section. Public members in TextArea are accessible from anywhere. Private members are not visible from outside the class. The default visibility allows access by other classes in the package.

Figure 6-7. Private, default, protected, and public visibility

The protected modifier allows special access permissions for subclasses. Contrary to how it might sound, protected is slightly less restrictive than the default level of accessibility. In addition to the default access afforded classes in the same package, protected members are visible to subclasses of the class, even if they are defined in a different package. If you are a C++ programmer used to more restrictive meanings, this may rub you the wrong way.[18]

Table 6-1 summarizes the levels of visibility available in Java; it runs generally from most to least restrictive. Methods and variables are always visible within a declaring class itself, so the table doesn’t address that scope.

Table 6-1. Visibility modifiers

Modifier

Visibility outside the class

private

None

No modifier (default)

Classes in the package

protected

Classes in package and subclasses inside or outside the package

public

All classes

Subclasses add two important (but unrelated) complications to the topic of visibility. First, when you override methods in a subclass, the overriding method must be at least as visible as the overridden method. While it is possible to take a private method and override it with a public method in a subclass, the reverse is not possible; you can’t override a public method with a private method. This restriction makes sense if you recall that subtypes have to be usable as instances of their supertype (e.g., a Mammal is a subclass of Animal and, therefore, must be usable as an Animal). If we could override a method with a less visible method, we would have a problem: our Mammal might not be able to do all the things an Animal can. However, we can reduce the visibility of a variable. In this case, the variable acts like any other shadowed variable; the two variables are distinct and can have separate visibilities in different classes.

The next complication is a bit harder to follow: the protected variables of a class are visible to its subclasses, but only through objects of the subclass’s type or its subtypes. In other words, a subclass can see a protected variable of its superclass as an inherited variable, but it can’t access that same variable via a reference to the superclass itself. This statement could be confusing because it might not be obvious that visibility modifiers don’t restrict access between instances of the same class in the same way that they restrict access between instances of different classes. Two instances of the same class can access all of each other’s members, including private ones, as long as they refer to each other as the correct type. Said another way: two instances of Cat can access all of each other’s variables and methods (including private ones), but a Cat can’t access a protected member in an instance of Animal unless the compiler can prove that the Animal is a Cat. That is, Cats have the special privileges of being an Animal only with respect to other Cats, not just any Animal. If you find this hard to follow, don’t worry too much. If you run into this as a problem in the real world, you are probably trying to do something trickier than you should.

Interfaces behave like classes within packages. An interface can be declared public to make it visible outside its package. Under the default visibility, an interface is visible only inside its package. Like classes, only one public interface can be declared in a compilation unit (file).

Get Learning Java, 4th Edition now with the O’Reilly learning platform.

O’Reilly members experience live online training, plus books, videos, and digital content from nearly 200 publishers.

Access modifiers are object-oriented programming that is used to set the accessibility of classes, constructors, methods, and other members of Java.
Using the access modifiers we can set the scope or accessibility of these classes, methods, constructors, and other members. 

JAVA has two types of modifiers: access modifiers and non-access modifiers.

What are Access Modifiers?

Access modifiers are keywords that can be used to control the visibility of fields, methods, and constructors in a class. The four access modifiers in Java are public, protected, default, and private.

Four Types of Access Modifiers

  • Private: We can access the private modifier only within the same class and not from outside the class.
  • Default: We can access the default modifier only within the same package and not from outside the package. And also, if we do not specify any access modifier it will automatically consider it as default.
  • Protected: We can access the protected modifier within the same package and also from outside the package with the help of the child class. If we do not make the child class, we cannot access it from outside the package. So inheritance is a must for accessing it from outside the package.
  • Public: We can access the public modifier from anywhere. We can access public modifiers from within the class as well as from outside the class and also within the package and outside the package.

For a refresher, check out this free course on Java programming. On completion, you will also earn a certificate which is sure to put you ahead in the competitive space.

Let us see which all members of Java can be assigned with the access modifiers:

Members of JAVAPrivateDefaultProtectedPublic
ClassNoYesNoYes
VariableYesYesYesYes
MethodYesYesYesYes
ConstructorYesYesYesYes
interfaceNoYesNoYes
Initializer BlockNOT ALLOWED

Now let us understand the scope of these access modifiers with the help of a table:

AccessibilityPrivateDefaultProtectedPublic
Same PackageSame ClassYesYesYesYes
Without InheritanceNoYesYesYes
With InheritanceNoYesYesYes
Different PackageWithout InheritanceNoNoNoYes
With InheritanceNoNoYesYes

Let’s understand with more details:

Also, check Top Java Interview Questions and Answers for Freshers

Private Access Modifier

  • The private access modifier is specified when any member of a class is prefixed with the private keyword. In comparison with the other access modifiers, this is the most restricted access modifier. 
  • When the methods or data members are prefixed with a private access modifier, the visibility of these methods and data members are restricted so, they can be accessed only within the same class where they have been declared, they will not be visible to the outside world. 
  • If we have another class from the same package still, we will not be able to access these methods or data members. So usually, we keep the class variables and methods as private, which are intended to be used inside the same class where declared.  

Let us consider an example where we will consider two classes A1 and A2 within the same package p1. We will declare a variable and a method as private in class A1 and then try to access these methods and variables from class A2. 

So here we will Compile Time Error.

Let us see for a private constructor:

If we make any class constructor private, we cannot create the instance of that class from outside the class, and hence, from here we can conclude that the private access modifier can be accessed only within the same class and not from outside the class.

Default Access Modifier

  • It is not a keyword. Any Java members such as class or methods or data members when not specified with any access modifier they are by default considered as default access modifiers.  These methods or data members are only accessible within the same package and they cannot be accessed from outside the package. It provides more visibility than a private access modifier. But this access modifier is more restricted than protected and public access modifiers.

Let us consider an example for the default access modifier.

Here, we have two different packages p1 and p2. In the p1 package, we have class A1 where we declared a default variable and a default method. Now we are trying to access this variable and method from outside the package that is from package p2 which has a class A2. 

When we try to access these variables and methods from outside the package we get a Compile time error.

Hence, we conclude that the default access modifier members can be accessed only within the same package and cannot be accessed from outside the package. And they have more visibility than private access modifier but is more restricted than protected and public access modifiers.

Protected Access Modifier

  • It is a keyword. This access modifier is used to access the methods or data members of a class within the same package as well as outside the package but only through inheritance. The protected access modifier has more accessibility than private and defaults access modifiers. But it has less visibility than the public access modifier.

Let us consider an example for a protected access modifier. 

Here we have two packages p1 and p2. In package p1 we have class A1 where we have declared a protected test method. In package p2 we are inheriting the members of class A1 inside class A2 with help of extending keywords and creating a relationship between the two classes. We can also say that class A1 is the parent class or the superclass and class A2 is the child class or the subclass respectively.

When we inherit the members of class A1 inside class A2, with the help of a protected access modifier we can access the members of class A1 of package p1 from class A2 of the different package p2.

So here we get the output as Hi I’m from a protected method. 

Hence, we can conclude that the methods, variables, and data members of a class prefixed with a protected access modifier can be accessed within the same package as well as can be accessed from outside the package but only with the help of inheritance.

Public Access Modifier

It is a keyword. If a class member like variable, method, or data members are prefixed with a public access modifier, then they can be accessed from anywhere inside the program. That is, they can be accessed within the same class as well as from outside the different classes. 

It also includes access within the same package and also from outside the package. The members like variables, methods, and other data members can be accessed globally. 

Using public access modifiers we can provide access to the members most simply. There are no restrictions on public access modifier members. Hence, it has the widest accessibility or visibility scope as compared to the rest of the access modifiers.

Let us now consider an example of public access modifier.

Here in this example, we have two different packages p1 and p2. In p1 we have a class a1 where we have declared a variable and a method prefixed public keyword. And in the p2 package, we have a class A2 from where we are trying to access the members of class A1 without inheritance.

Here we get the output as 10 and Hi I’m from the public method.

So from the above example, we can conclude that public access modifier members can be accessed from anywhere, within the same class as well as from outside the class. And also can be accessed within the same package and also from outside a package.

NOTE: If any other developer is using your class, then try to use the most restricted access modifier. And also try to use a private access modifier, wherever necessary.

An overall accessibility:

private<default<protected<public.

JAVA Access Modifiers with Method Overriding

When overriding a method, the method which is overridden should not be restrictive.

For example:

In the above example, the test method is been overridden in class A2. But the subclass method should have the same visibility or more visibility than the superclass method. Since the subclass method has less scope than the superclass method, we get a compile-time error.