Access Modifiers

It's important to know the information in this section, but you can skim through it on the first reading. It explains how we can use keywords to make things more widely or narrowly visible.

There are three or four keywords that are applied to class members. These keywords are collectively called the access modifiers. By default, a member is only visible to classes in its own package. Certain keywords make them visible inside the class (only), or inside the inheritance hierarchy, or to classes in other packages.

Access modifiers for a class

Class declarations can be nested inside other classes. It's a design choice you'd make when the nested class is a helper or utility for the top level class. E.g. the top level class java.lang.Character contains a nested class called java.lang.Character.UnicodeBlock.

package java.lang;
public class Character {   /* a top level class */
      /* lots of code */
      public class UnicodeBlock { /*a nested class*/  }
}

That nested class organizes and gives names to several chunks of Unicode characters. You've got your Basic Latin block, your Extended Latin block, your Greek block, your Cyrillic block, and so on all the way to the Chinese and Japanese character blocks. The UnicodeBlock class was put inside Character because it provides some services intimately tied to Character. However it is public so anyone can use it (e.g. to test if a certain character is in the range of Greek characters).

Most of the classes you write will be top level (not nested) classes. Top level classes are always visible to other classes in the same package. They are only visible in other packages when you prefix the class definition with the access modifier “public”. The term “visible” means you can see and access the resource (call a method, read a field, whatever it is). Here are the two cases of visibility of a top level class:

  • If you don't use any access modifier

      package a.b.c;
      class D {  /*some code */ }

    Class D will be visible only to classes in the same package a.b.c, (typically this means the same directory) and nowhere else.

  • If you use the public access modifier

      package a.b.c;
      public class D {  /*some code */ }

    Class a.b.c.D will be visible to all packages everywhere.

Good programming practice says that you should give resources the least possible visibility compatible with them being able to carry out their work. Certainly the only public resources should be those that you intend to be part of the API of your system.

Access modifiers for a method, field, or nested class

The constructors and members of a class have finer granularity of visibility than top-level classes. That lets you fine-tune the visibility of resources beyond just the on/off that classes provide. But if a class isn't visible, then none of its members will be either, regardless of their access modifiers. Here's a reminder of how constructors and members look in a class.

package a.b.c;
public class D {
     D() { /*some code*/ }            // constructor

             // the class members
     int i;                           // data field
     int getValue() { return i; }     // method
     class mynested { /*more code*/ } // nested class
}

Just like top-level classes, a member might have no access modifier or the keyword public. There are two additional modifiers for members, protected and private, giving four cases of visibility.

  • No access modifier

    /*no modifier*/ int getValue() { return i; }

    The member will be visible only to classes in the same package a.b.c, and nowhere else. This is often called “package access” because that starts with a “P” like the other choices. The JLS calls it “default access”.

  • The public access modifier

      public int getValue() { return i; }

    The member will be visible to classes in all packages everywhere.

  • The private access modifier

      private int getValue() { return i; }

    The member will be visible only inside the top level class, and nowhere outside.

  • The protected access modifier

      protected int getValue() { return i; }

    The member will be visible to classes in this package, and subclasses everywhere. But watch out! This does not work the way you might think. See the discussion of “clone” in Chapter 11.

Here is an OOP code idiom that uses access modifiers to allow read-only access to a field:

public class Employee {
     private long salary;     // field is NOT visible to other classes

     public long getSalary() { // method is visible to other classes
          return salary;
     }
    /* more code*/
}


class SomeOtherClassEntirely {

     public void main() {
          Employee e = new Employee(); /*more code*/
          long pay = e.getSalary();// gets the salary field of e

In the preceding example, the salary field is private and cannot be accessed outside the Employee class. However, the Employee class can define an accessor method that is not private and that reads the value and returns it. Accessor functions frequently occur in pairs, with the name getSomething() to read it, and setSomething(x newValue) to set it. The setSomething() method is called a mutator method, and is often given protected visibility. Do this when you want any class to be able to get a field, but only child classes to be able to set the field.

That finishes the discussion of visibility. On to the Light Relief!

But first the Exercises!

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

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