Encapsulation and access control

Figure 210. Access control: Overall objectives Slide presentation

Figure 211. Example: Two ways implementing a day's time Slide presentation
public class DayTime {
  private int  minutes_since_0_00;

  public int getMinute() { 
    return minutes_since_0_00 % 60;
  }
  public int getHour() {
    return minutes_since_0_00 / 60;
  }
}
public class DayTime {
  private int minute, hour;
         
  public int getMinute() { 
        return minute;
  }
  public int getHour() { 
        return hour;
  }
}

Private attributes only accessible by methods belonging to class.

public items accessible also by alien classes.


Figure 212. Access violation Slide presentation

No access to private field of alien class Time:

public class Q {
  public static void main(String[] args) {

      Time t = new Time();

      // Error: 'minutes_since_0_00' has private access in 'Time'
      t.minutes_since_0_00 = 371;
  }
}

Figure 213. Access rules Slide presentation
Access Level Other package Child class Same package Same class
public yes yes yes yes
protected no yes yes yes
Default no no yes yes
private no no no yes

  • Use the most restrictive access level that makes sense for a particular member.

  • Use private unless you have a good reason not to.

  • Avoid public fields except for constants. Public fields tend linking to a particular implementation and limit your flexibility in changing your code.


exercise No. 91

Understanding access control

Q:

Follow the example given in Classes and Packages of the Example Used to Illustrate Access Levels and define two respective classes Alpha and Beta in different packages. Supply suitable dummy methods and fields illustrating both legal and illegal access.

A:

Alpha Beta AlphaSub Gamma
package package_one;

public class Alpha {

  public     int attribPublic;
  protected  int attribProtected;
/*Default*/  int attribDefault;
  private    int attribPrivate;

  void dummy(/* same class */) {
    int v;
    v = attribPublic;
    v = attribProtected;
    v = attribDefault;
    v = attribPrivate;
  }
}
package package_one;

public class Beta {






  void dummy(Alpha a) {
    int v;
    v = a.attribPublic;
    v = a.attribProtected;
    v = a.attribDefault;
    v = a.attribPrivate;
  }
}
//different package
package package_two;

import package_one.Alpha;

public class AlphaSub
              extends Alpha {


  void dummy(/* Inherited */) {
    int v;
    v = attribPublic;
    v = attribProtected;
    v = attribDefault;
    v = attribPrivate;
  }
}
//different package
package package_two;
import package_one.Alpha;

public class Gamma {




  void dummy(Alpha a) {
    int v;
    v = a.attribPublic;
    v = a.attribProtected;
    v = a.attribDefault;
    v = a.attribPrivate;
  }
}

Note

Notice the related follow up inheritance exercise.

exercise No. 92

Explaining times

Q:

In Figure 211, “Example: Two ways implementing a day's time ” we have:

public int getMinute() { 
    return minutes_since_0_00 % 60;
}

Explain the term minutes_since_0_00 % 60's underlying idea.

A:

Every 60 minutes a new hour begins and minutes start from zero again.

The term minutes_since_0_00 / 60 amounts to the number of hours passed since 0:00 or midnight. Building the remainder minutes_since_0_00 % 60 provides the current minute.

Example: If there are 134 minutes elapsed since midnight this amounts to 134 / 60 == 2 hours and 134 % 60 == 14 minutes.