Richard G Baldwin (512) 223-4758, baldwin@austin.cc.tx.us, http://www2.austin.cc.tx.us/baldwin/

Access Control

Java Programming, Lecture Notes # 40, Revised 10/03/99.

Preface
Introduction
Access Control in Java
Access Control in C++
Review

Preface

Students in Prof. Baldwin's Introductory Java Programming classes at ACC are responsible for knowing and understanding all of the material in this lesson (except that they are not responsible for detailed information that is specific to C++).

The detailed material on C++ is provided as supplementary material for the benefit of persons already familiar with C++ who are making the transition into Java.

The material in this lesson is very important. However, there is simply too much material to be covered in
detail during lecture periods. Therefore, students in Prof. Baldwin's Introductory Java Programming
classes at ACC will be responsible for studying this material on their own, and bringing any questions
regarding the material to class for discussion.

Introduction

Both Java and C++ support the notion of controlling access to the individual members of a class (either variables or methods).

Java also supports the notion of controlling access to the class itself.

Also, both languages support the notion of inheritance. With inheritance, it is possible to create a new class by inheriting the attributes of an existing class.

The class being inherited from is often called the base class or the superclass. The class which is inherited is often called the derived class or the subclass.

When an object is instantiated from a subclass, that object contains all the members of the new class, plus all the members of the inherited class, plus all the members of its ancestors.

However, access to the members of that object may be impacted by the access control modifiers applied to the members of the superclass.

Access Control in Java

Protected
Package
Private
Public

Access control in Java is difficult for some students to understand. It is also difficult to explain in ways that people can understand. I own many good books on Java programming, and none of them explain access control to my satisfaction.

Don't depend entirely on this lesson, or any other single source for your understanding of access control. Because of its complexity, I recommend that you go to a bookstore and read what a large number of Java books have to say about this topic. This will give you an understanding of access control from the viewpoint of many different authors. In particular, I recommend that you take a look at the "rules of thumb" given by David Flanagan in his excellent book, Java in a Nutshell.

This lesson is my attempt to explain access control. I am hopeful that you will understand it when you finish this lesson.

Because of the complexity of access control, it is also very easy to make technical errors when producing an explanatory document like this. I have been as careful as I know how to avoid technical errors in my explanation of access control, but some errors may have crept in.

I will welcome email messages from readers who find and identify such errors. If you find an error, please describe it and provide sufficient technical backup that I can evaluate your description.

Access control is implemented in Java by applying access modifiers to individual members in the class definition. Java implements four different access modifiers that may be applied to any individual member of a class:

Let me explain the last modifier in the list a little further. If no modifier is applied to a member of a class, then that member has what I will refer to as package access.

The first two, public and private are pretty simple and don't lead to a lot of complexity. The complexity arises with protected and package, and particularly with respect to the interaction of these two modifiers with the inheritance of classes in the same or different packages.

In Java, special access privileges are afforded to members of other objects which are instantiated from classes contained in the same package and this occurs by way of the package access modifier.

In addition, special access privileges are afforded to certain members of superclasses and this occurs by way of the protected modifier.

I am going to start with some statements regarding access control that I believe to be true although in some cases, they don't present the complete picture. Hopefully the tables that follow will provide the complete picture.

In the following statements, when I speak of the collective superclass, I am speaking not only of the immediate superclass, but of all of the classes in the inheritance hierarchy from that class up to and including the class named Object.

I didn't include any sample programs in this lesson. I wrote and tested literally dozens of short sample programs to confirm what I thought to be true about access control. However, none of them were sufficiently complicated to merit being included in the lesson and if I had included them all, they would have consumed many pages of space.

At this point in the course, you should have no difficulty writing your own programs to test any given hypothesis about access control.

I'm going to begin with a couple of statements about access control at he class level. This is a fairly simple topic so I won't have any more to say about it following these statements.

Now I will present some statements that bear on access control of individual members of a class. Unfortunately, they tend to read like a contract, but I don't know how to avoid that situation.

Same Class Member Access:

Subclass access:

private Member Access:

public Member Access:

protected Member Access:

package Member Access:

As mentioned earlier, public and private access control isn't too difficult to understand. package access can become complicated when you overlay it with package considerations involving inheritance.

Most of the confusion revolves around protected access control, and this confusion derives from the fact that the behavior differs depending on whether you are discussing access of protected members of a superclass

Most practical programming scenarios probably involve the first of the two situations listed above. If you can remember the rules governing that situation, you will probably have most of your bases covered. A large portion of the remainder of this lesson is dedicated to explaining and clarifying the complex rules governing the second situation listed above in case you encounter that situation.

Most of the books attempt to encapsulate this complexity into a two-dimensional chart which is about four or five cells on each side. I have yet to see such a two-dimensional chart in any book that does justice to the topic of access control of protected members, and to some extent package members as well..

In fact, most of the charts in most of the books tend to lead to erroneous conclusions regarding access control of protected and package members because they don't take inherited members into account in a satisfactory manner. And you don't need charts to describe public and private, so most of the charts that I have seen are not very useful. (Hopefully mine will be more useful, but that will be for you to decide.)

The situation can be represented reasonably well by a three-dimensional chart, but three-dimensional charts are difficult to display on a flat surface. In this lesson, I have essentially created a three-dimensional chart (a cube with four layers) and have presented the four individual layers for your consideration. My charts don't include all possible situations, but I believe you will find that they do cover most of the situations that you will encounter.

To understand the charts, assume that there are two objects named A and B. Code in object A is attempting to access members of object B.

The members of object B can have public, private, protected, or package access. The members of object B can either be defined in the class definition from which object B is instantiated, or can be inherited from a superclass of that class. (It is this latter possibility that leads to much of the complexity.)

I have attempted to identify most of the interesting relationships between object A and object B, and describe the accessibility of the members of object B by the code in object A.

There are several situations that we must consider, each of which has two states. The situations are:

Object B may or may not be the same object as object A. If so, object A is attempting to access its own members which may have originated in its own class definition, or may have originated in a superclass of that class.

Object B may or may not be of the same class as Object A. (By the way, when I say that object B is "of the same class" what I really mean is "was instantiated from the same class." I use the shorter form for brevity.)

Object B may or may not be of a class that is in the same package as object A.

The class of object B may or may not be a superclass of object A.

The class member of interest may or may not be inherited into the object from a superclass.

If the member was inherited into the object, it is a member of a class that may or may not be in the same package as the object that it was inherited into.

If all possible combinations of these various situations were possible, this would give us very large number of different scenarios that we would need to consider. Fortunately, many of the possible combinations are not possible. For example, if object B is of the same class as object A, then it cannot possibly be of a superclass of object A, because a class cannot extend itself.

Therefore, after we eliminate impossible combinations of the possible situations, we are left with a manageable number of scenarios to consider. We must consider each scenario for each of the four access control modifiers: public, private, protected, and package.

Protected

As mentioned earlier, the protected modifier probably leads to the most confusion, so I will begin with it. I will present four tables with the same format, one table for each of the access control modifiers.

The format of the table identifies the access control modifier applied to the class member of interest in the upper left-hand corner.

For each row in the table, the first column indicates whether or not a class member with the specified access control modifier in object B is accessible to code in object A for the set of conditions listed in the cells to the right of the first column.

In addition, notes are referenced in the table and presented following the table that attempt to explain each answer.

While all of the rows contain important information, you should pay particular attention to the last row. This is the situation where object B and object A are the same object as described earlier.

The last row describes the situation where code in the methods of an object is attempting to access the other members of that same object. This is an especially important case for protected members, because this is how access to certain members is passed down the inheritance hierarchy without opening access to those members up to the rest of the world.

All of the other rows represent the case where code in the methods of one object is attempting to access the members of a different object.

Remember, this table represents one layer of a cube that has four layers. The other three layers will be presented later in this lesson.

Member of object B is protected

Object B in relation to object A:

Is member of object B Accessible by code in object A?

Is object B the same object as object A?

Is object B of the same class as object A?

Is the class of object B in the same package as the class of object A?

Is object B of a class that is a superclass of the class of Object A?

Is the member inherited, and if so, from what package?

No - See note 1

No

No

No

No

Don't care

No - See note 1

No

No

No

Yes

Don't care

Yes - See note 2

No

No

Yes

No

No

Yes - See note 2

No

No

Yes

No

Yes, from same package

No - See note 2

No

No

Yes

No

Yes, from different package

Yes - See note 3

No

No

Yes

Yes

No

Yes - See note 3

No

No

Yes

Yes

Yes, from same package

No - See note 3

No

No

Yes

Yes

Yes, from different package

Yes - See note 4

No

Yes

Yes

No - Can't Be

No

Yes - See note 4

No

Yes

Yes

No - Can't Be

Yes, from same package

Yes - See note 4

No

Yes

Yes

No - Can't Be

Yes, from different package

Yes - See note 5

Yes

Yes - Must be

Yes - Must be

No - Can't Be

Don't care

Note 1 - protected members of object B are not accessible by code in object A if object B is in a different package regardless of whether or not object B is of a class that is a superclass of object A.

Note 2 - protected members of object B are accessible by code in object A if the class of object B is in the same package as object A. Note however, that package members of object B that are inherited from a superclass are accessible by object A only if the superclass is in the same package as the class of object A.

Note 3 - When the class of object B is a superclass of the class of object A, protected members of object B are accessible by code in object A if the class of object B is in the same package as object A. Note however, that protected members of object B that are inherited from a superclass are accessible by object A only if the superclass is in the same package as the class of object A.

Note 4 - When object A and object B are of the same class, protected members of object B are accessible by code in object A. Note that protected members of object B that are inherited from a superclass are accessible by object A even if the superclass is not in the same package as the class of object A.

Note 5: When object A and object B are the same object, all protected members of that object are accessible within the code of the object whether those protected members are defined in the class of the object, or in a superclass of the object irrespective of the package in which the superclass resides.

Package

The next most complicated modifier is package. At the surface, this sounds like an easy modifier to describe and to understand, and it is until you start taking into account that package members can be inherited into an object from a superclass that may, or may not be in the same package.

Therefore, you can't simply say that code in an object has access to the members of all other objects instantiated from classes in the same package. Whether or not access is granted for a particular package member depends on how the member came to be part of the object in the first place:

part of the same package, or

not part of the same package.

Again, in this case, pay particular attention to the last three rows. These three rows represent the situation where object A and object B are the same object. These three rows address the possibility of members with package access being contained in the object:

As you will see, the accessibility of the package members within the object is not the same across these three cases.

Member of object B is package

Object B in relation to object A:

Is member of object B Accessible by code in object A?

Is object B the same object as object A?

Is object B of the same class as object A?

Is the class of object B in the same package as the class of object A?

Is object B of a class that is a superclass of the class of Object A?

Is the member inherited, and if so, from what package?

No - See note 1

No

No

No

No

Don't care

No - See note 1

No

No

No

Yes

Don't care

Yes - See note 2

No

No

Yes

No

No

Yes - See note 2

No

No

Yes

No

Yes from same package

No - See note 2

No

No

Yes

No

Yes from different package

Yes - See note 3

No

No

Yes

Yes

No

Yes - See note 3

No

No

Yes

Yes

Yes from same package

No - See note 3

No

No

Yes

Yes

Yes from different package

Yes - See note 4

No

Yes

Yes

No - Can't Be

No

Yes - See note 4

No

Yes

Yes

No - Can't Be

Yes from same package

No - See note 4

No

Yes

Yes

No - Can't Be

Yes from different package

Yes - See note 5

Yes

Yes - Must be

Yes - Must be

No - Can't Be

No

Yes - See note 5

Yes

Yes - Must be

Yes - Must be

No - Can't Be

Yes from same package

No - See note 5

Yes

Yes - Must be

Yes - Must be

No - Can't Be

Yes from different package

Note 1 - package members of object B are not accessible by code in object A if object B is in a different package regardless of whether or not object B is of a class that is a superclass of object A.

Note 2 - package members of object B are accessible by code in object A if the class of object B is in the same package as object A. Note however, that package members of object B that are inherited from a superclass are accessible by object A only if the superclass is in the same package as the class of object A.

Note 3 - When the class of object B is a superclass of the class of object A, package members of object B are accessible by code in object A if the class of object B is in the same package as the class of object A. Note however that package members of object B that are inherited from a superclass are accessible by object A only if the superclass is in the same package as the class of object A.

Note 4 - When object A and object B are of the same class, package members of object B are accessible by code in object A. Note however that package members of object B that are inherited from a superclass are accessible by object A only if the superclass is in the same package as the class of object A.

Note 5 - When object A and object B are the same object, package members of that object are accessible by the code in that object so long as they are defined in the class of the object, or are inherited from a superclass that is in the same package as the class of the object. However, package members that are defined in a superclass in a different package are not accessible.

Private

As mentioned earlier, private access control is pretty easy to understand. Because of its relative simplicity, it was possible for me to collapse the table into three rows that represent two different cases: in one case, object A and object B are not the same object, and in the other case, they are the same object.

The second case was subdivided into two sub-cases: one where the private member was not inherited, and the other case where it was inherited. As you will see, in one of these two latter cases, the private member is accessible and in the other case it is not accessible.

Member of object B is private

Object B in relation to object A:

Is member of object B Accessible by code in object A?

Is object B the same object as object A?

Is object B of the same class as object A?

Is the class of object B in the same package as the class of object A?

Is object B of a class that is a superclass of the class of Object A?

Is the member inherited, and if so, from what package?

No - See note 1

No

Don't care

Don't care

Don't care

Don't care

Yes - See note 2

Yes

Yes - Must be

Yes - Must be

No - Can't Be

No

No - See note 2

Yes

Yes - Must be

Yes - Must be

No - Can't Be

Yes from same or different package

Note 1 - private members of object B are not accessible by code in object A unless object B is the same object as object A. private members can only be accessed by code defined in the same class where the private member is defined.

Note 2 - private members of object B are accessible by code in object A if object B and object A are the same object, except that private members of object B that are inherited from a superclass are not accessible by object A regardless of the package of the superclass.

Public

The simplest case of all is the case of public members. In fact, this case is so simple that I was able to collapse the entire table into a single row with the answer being that: yes, the public member of object B is accessible by code in object A without regard to the answers to the questions posed by columns 2 through 6.

Be aware that if I were going to attempt to use these tables to construct the three-dimensional, four-layer cube that I talked about earlier, it would not be possible for me to do this collapsing. All four tables would have to have the same dimensions. That would simply mean that there would be cells in the table containing redundant information because the collapsing was accomplished by removing redundancies.

Member of object B is public

Object B in relation to object A:

Is member of object B Accessible by code in object A?

Is object B the same object as object A?

Is object B of the same class as object A?

Is the class of object B in the same package as the class of object A?

Is object B of a class that is a superclass of the class of Object A?

Is the member inherited, and if so, from what package?

Yes - See note 1

Don't care

Don't care

Don't care

Don't care

Don't care

Note 1 - public members of object B are accessible by code in object A or code in any other object that is within the scope of object B.

Access Control in C++

In C++, any individual member of a class in can be designated as private, public or protected. A member which is designated private can be accessed only by other members of the same class. This is the most restrictive of the three designations.

Note that a private member of a base class cannot be accessed by members of an inherited class, regardless of the application of access control at the inheritance interface as discussed below.

A member which is designated as public can be accessed by any code within the scope of an object instantiated from that class. This is the least restrictive of the three designations.

The protected designation comes into play only when inheritance is involved. Stated simply, a member which is designated as protected appears to be public to members of classes which are derived from that class and appears to be private otherwise (subject to the application of additional access control at the inheritance interface as discussed below).

Access Control at the Inheritance Interface

The first dimension of access control in C++ which was discussed above has its analog in Java.

Access control in C++ has a second dimension for which there is no Java analog.

Whenever one class is inherited from another class, a second level of access control is specified at the inheritance interface using the same three keywords: public, private, and protected.

Let's begin this discussion with two statements:

  • The access control applied to a particular member of a class cannot be made less restrictive through the application of access control at the inheritance interface.
  • Application of access control at the inheritance interface will elevate the access restriction applied to an individual member to the level specified at the inheritance interface if it is not already at that level or above.

Applying public access control at the inheritance interface will have no effect on the accessibility of members of the original class in objects of the derived class.

Applying private access control at the inheritance interface will cause all members of the original class to become private members of the derived class.

Applying protected access control at the inheritance interface will cause all public members of the original class to become protected members of the new class, and will cause all protected members of the original class to become protected members of the new class. Private members of the original class remain private and cannot be accessed by members of the new class.

It is important to note that access control is applied at the class level and not at the object level. That is to say, the instance methods of any object of a particular class have direct access to the private members of any other object of the same class.

Friend Functions

There is one additional aspect of access control in C++ that must be noted. A function can be designated as a friend of a class, in which case it has direct access to all the private and protected members of that class. That function can be a member function (method) of another class, or can simply be a stand-alone function (stand-alone functions are not supported in Java).

Java has no direct analogy to friend functions in C++.

Review

Q - Three keywords are used in Java to specify access control. What are they?

A - The three keywords used to specify access control in Java are public, private, and protected.

Q - Java provides three different levels of access control- public, private, and protected: True or False? If false explain your answer.

A - False. Java has four levels of access control. Java implements three access specifiers using the keywords public, private, and protected, and in addition, implements a fourth level of access control if none of the other three are specified in the class definition. (This access control level is often referred to as package, default or friendly.) Prior to JDK 1.1, there were five levels of access control including private protected. However, private protected is not supported by JDK 1.1.

Q - In Java, special access privileges are afforded to other members of the same package: True or False? If false, explain your answer.

A - True. In Java, special access privileges are afforded to other members of the same package.

Q - As a guideline, you should use private protected access for methods and variables that aren't necessary to use the class, but that may be of interest to anyone extending the class. True or False? If false, explain your answer.

A - False. private protected access is no longer allowed in JDK 1.1.1.

-end-