1.4.1. Access modifiers

Let’s start with an example. Examine the definitions of the classes House and Book in the following code and the UML representation shown in figure 1.20.

Figure 1.20. The nonpublic class Book can’t be accessed outside the package library.

package building;
class House {}
package library;
class Book {}

With the current class definitions, the class House can’t access the class Book. Can you make the necessary changes (in terms of the access modifiers) to make the class Book accessible to the class House?

This one shouldn’t be difficult. From the discussion of class declarations in section 1.1, you know that a top-level class can be defined only by using the public or default access modifiers. If you declare the class Book using the access modifier public, it’ll be accessible outside the package in which it is defined.

Note

A top-level class is a class that isn’t defined within any other class. A class that is defined within another class is called a nested or inner class. Nested and inner classes aren’t on the OCA Java SE 8 Programmer I exam.

What do they control?

Access modifiers control the accessibility of a class or an interface, including its members (methods and variables), by other classes and interfaces within the same or separate packages. By using the appropriate access modifiers, you can limit access to your class or interface and their members.

Can access modifiers be applied to all types of Java entities?

Access modifiers can be applied to classes, interfaces, and their members (instance and class variables and methods). Local variables and method parameters can’t be defined using access modifiers. An attempt to do so will prevent the code from compiling.

How many access modifiers are there: three or four?

Programmers are frequently confused about the number of access modifiers in Java because the default access isn’t defined using an explicit keyword. If a Java class, interface, method, or variable isn’t defined using an explicit access modifier, it is said to be defined using the default access, also called package access.

Java has four access levels:

  • public (least restrictive)
  • protected
  • default
  • private (most restrictive)

To understand all of these access levels, we’ll use the same set of classes: Book, CourseBook, Librarian, StoryBook, and House. Figure 1.21 depicts these classes using UML notation.

Figure 1.21. A set of classes and their relationships to help you understand access modifiers

Classes Book, CourseBook, and Librarian are defined in the package library. The classes StoryBook and House are defined in the package building. Further, classes StoryBook and CourseBook (defined in separate packages) extend class Book. Using these classes, I’ll show how the accessibility of a class and its members varies with different access modifiers, from unrelated to derived classes, across packages.

As I cover each of the access modifiers, I’ll add a set of instance variables and a method to the class Book with the relevant access modifier. I’ll then define code in other classes to access class Book and its members.

1.4.2. Public access modifier

This is the least restrictive access modifier. Classes and interfaces defined using the public access modifier are accessible across all packages, from derived to unrelated classes.

To understand the public access modifier, let’s define the class Book as a public class and add a public instance variable (isbn) and a public method (printBook) to it. Figure 1.22 shows the UML notation.

Figure 1.22. Understanding the public access modifier

Definition of class Book:

The public access modifier is said to be the least restrictive, so let’s try to access the public class Book and its public members from class House. We’ll use class House because House and Book are defined in separate packages and they’re unrelated.

Note

The term unrelated classes in this chapter refers to classes that don’t share inheritance relation. For instance, classes House and Book are unrelated, if neither House derives from Book nor Book derives from House.

Class House doesn’t enjoy any advantages by being defined in the same package or being a derived class.

Here’s the code for class House:

In the preceding example, class Book and its public members—instance variable isbn and method printBook—are accessible to class House. They are also accessible to the other classes: StoryBook, Librarian, House, and CourseBook. Figure 1.23 shows the classes that can access a public class and its members.

Figure 1.23. Classes that can access a public class and its members

1.4.3. Protected access modifier

The members of a class defined using the protected access modifier are accessible to

  • Classes and interfaces defined in the same package
  • All derived classes, even if they’re defined in separate packages

Let’s add a protected instance variable author and a method modifyTemplate to the class Book. Figure 1.24 shows the class representation.

Figure 1.24. Understanding the protected access modifier

Here’s the code for the class Book (I’ve deliberately left out its public members because they aren’t required in this section):

Figure 1.25 illustrates how classes from the same and separate packages, derived classes, and unrelated classes access the class Book and its protected members.

Figure 1.25. Access of protected members of the class Book in unrelated and derived classes, from the same and separate packages

Class House fails compilation for trying to access the method modifyTemplate and the variable author. Following is the compilation error message:

House.java:8: modifyTemplate() has protected access in library.Book
        book.modifyTemplate();
            ^
Note

Java code fails compilation because of syntax errors. In such a case, the Java compiler notifies the offending code with its line number and a short description of the error. The preceding code is output from the compilation process. This book uses the command prompt to compile all Java code.

A derived class inherits the protected members of its base class, irrespective of the packages in which they’re defined.

Notice that the derived classes CourseBook and StoryBook inherit class Book’s protected member variable author and method modifyTemplate(). If class StoryBook tries to instantiate Book using a reference variable and then tries to access its protected variable author and method modifyTemplate(), it won’t compile:

Exam Tip

A concise but not too simple way of stating the previous rule is this: A derived class can inherit and access protected members of its base class, regardless of the package in which it’s defined. A derived class in a separate package can’t access protected members of its base class using reference variables.

Figure 1.26 shows the classes that can access protected members of a class or interface.

Figure 1.26. Classes that can access protected members

1.4.4. Default access (package access)

The members of a class defined without using any explicit access modifier are defined with package accessibility (also called default accessibility). The members with package access are only accessible to classes and interfaces defined in the same package. The default access is also referred to as package-private. Think of a package as your home, classes as rooms, and things in rooms as variables with default access. These things aren’t limited to one room—they can be accessed across all the rooms in your home. But they’re still private to your home—you wouldn’t want them to be accessed outside your home. Similarly, when you define a package, you might want to make members of classes accessible to all the other classes across the same package.

Note

Although the package-private access is as valid as the other access levels, in real projects it often appears as the result of inexperienced developers forgetting to specify the access mode of Java components.

Let’s define an instance variable issueCount and a method issueHistory with default access in class Book. Figure 1.27 shows the class representation with these new members.

Figure 1.27. Understanding class representation for default access

Here’s the code for the class Book (I’ve deliberately left out its public and protected members because they aren’t required in this section):

You can see how classes from the same package and separate packages, derived classes, and unrelated classes access the class Book and its members (the variable issueCount and the method issueHistory) in figure 1.28.

Figure 1.28. Access of members with default access to the class Book in unrelated and derived classes from the same and separate packages

Because the classes CourseBook and Librarian are defined in the same package as the class Book, they can access the variables issueCount and issueHistory. Because the classes House and StoryBook don’t reside in the same package as the class Book, they can’t access the variables issueCount and issueHistory. The class StoryBook throws the following compilation error message:

StoryBook.java:6: issueHistory() is not public in library.Book; cannot be accessed from outside package
        book.issueHistory();
            ^

Class House is unaware of the existence of issueHistory()—it fails compilation with the following error message:

House.java:9: cannot find symbol
symbol  : method issueHistory()
location: class building.House
        issueHistory();
Defining a class Book with default access

What happens if we define a class with default access? What will happen to the accessibility of its members if the class itself has default (package) accessibility?

Consider this situation: Assume that Superfast Burgers opens a new outlet on a beautiful island and offers free meals to people from all over the world, which obviously includes inhabitants of the island. But the island is inaccessible by all means (air and water). Would awareness of the existence of this particular Superfast Burgers outlet make any sense to people who don’t inhabit the island? An illustration of this example is shown in figure 1.29.

Figure 1.29. This Superfast Burgers can’t be accessed from outside the island because the island is inaccessible by air and water.

The island is like a package in Java, and Superfast Burgers is like a class defined with default access. In the same way that Superfast Burgers can’t be accessed from outside the island in which it exists, a class defined with default (package) access is visible and accessible only from within the package in which it’s defined. It can’t be accessed from outside the package in which it resides.

Let’s redefine the class Book with default (package) access, as follows:

The behavior of class Book remains the same for the classes CourseBook and Librarian, which are defined in the same package. But class Book can’t be accessed by classes House and StoryBook, which reside in a separate package.

Let’s start with the class House. Examine the following code:

Class House generates the following compilation error message:

House.java:2: library.Book is not public in library; cannot be accessed from outside package
import library.Book;

Here’s the code of class StoryBook:

Figure 1.30 shows which classes can access members of a class or interface with default (package) access.

Figure 1.30. The classes that can access members with default (package) access

Because a lot of programmers are confused about which members are made accessible by using the protected and default access modifiers, the exam tip offers a simple and interesting rule to help you remember their differences.

Exam Tip

Default access can be compared to package-private (accessible only within a package), and protected access can be compared to package-private + kids (“kids” refer to derived classes). Kids can access protected methods only by inheritance and not by reference (accessing members by using the dot operator on an object).

1.4.5. private access modifier

The private access modifier is the most restrictive access modifier. The members of a class defined using the private access modifier are accessible only to themselves. It doesn’t matter whether the class or interface in question is from another package or has extended the class—private members are not accessible outside the class in which they’re defined. private members are accessible only to the classes in which they’re defined.

Let’s see this in action by adding a private method countPages to the class Book. Figure 1.31 depicts the class representation using UML.

Figure 1.31. Understanding the private access modifier

Examine the following definition of the class Book:

None of the classes defined in any of the packages (whether derived or not) can access the private method countPages. But let’s try to access it from the class CourseBook. I chose CourseBook because both of these classes are defined in the same package, and CourseBook extends the class Book. Here’s the code of CourseBook:

Because the class CourseBook tries to access private members of the class Book, it won’t compile. Similarly, if any of the other classes (StoryBook, Librarian, House, or Course-Book) tries to access the private method countPages() of class Book, it won’t compile.

Here’s an interesting situation: do you think a Book instance can access its private members using a reference variable? The following code won’t compile—even though variable b1 is of type Book, it’s trying to access its private method countPages outside Book:

Figure 1.32 shows the classes that can access the private members of a class.

Figure 1.32. No classes can access private members of another class

Note

For your real projects, it is possible to access private members of a classoutside them, using Java reflection. But Java reflection isn’t on the exam. So don’t consider it when answering questions on the accessibility of private members.

1.4.6. Access modifiers and Java entities

Can every access modifier be applied to all the Java entities? The simple answer is no. Table 1.3 lists the Java entities and the access modifiers that can be used with them.

Table 1.3. Java entities and the access modifiers that can be applied to them

Entity name

public

protected

private

Top-level class, interface, enum χ χ
Class variables and methods
Instance variables and methods
Method parameter and local variables χ χ χ

What happens if you try to code the combinations for an X in table 1.3? None of these combinations will compile. Here’s the code:

Watch out for these combinations on the exam. It’s simple to insert these small and invalid combinations in any code snippet and still make you believe that you’re being tested on a rather complex topic like threads or concurrency.

Exam Tip

Watch out for invalid combinations of a Java entity and an access modifier. Such code won’t compile.

Twist in the Tale 1.4

The following task was assigned to a group of programmers: “How can you declare a class Curtain in a package building so that it isn’t visible outside the package building?”

These are the answers submitted by Paul, Shreya, Harry, and Selvan. Which of these do you think is correct and why? (You can check your Twist in the Tale answers in the appendix.)

Programmer name

Submitted code

Paul package building; public class Curtain {}
Shreya package building; protected class Curtain {}
Harry package building; class Curtain {}
Selvan package building; private class Curtain {}

Your job title may assign special privileges or responsibilities to you. For example, if you work as a Java developer, you may be responsible for updating your programming skills or earning professional certifications in Java. Similarly, you can assign special privileges, responsibilities, and behaviors to your Java entities by using nonaccess modifiers, which are covered in the next section.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.14.252.56