/** Protected fields and methods are accessible to the subclasses of a class,
    but inaccessible to clients.

    Here we make the rating parameters of a symphony protected so that the
    opera subclass may access them directly.
*/

/* Movies, symphonies, operas are all special forms of attraction. */
class Attraction {

  /* Per-class default duration, accessible to sub-classes. */
  private static int defdur = 90;

  /* Per-instance actual duration. */
  private int duration = defdur;

  /* Methods to control access to instance variables. */

  public int duration () {
    return this.duration;
  }

  /* Constructor. */

  public Attraction (int d) {
    duration = d;
  }

}

/* A movie is a form of attraction. */
class Movie extends Attraction {

  /* Instance variables. */
  private int script, acting, directing;

  /* Constructor. */
  public Movie (int dur, int s, int a, int d) {
    super(dur);			// invoke the superclass constructor
    this.script = s; this.acting = a; this.directing = d;
  }
  
  /* Calculate the rating. */
  public int rating () {
    return (this.script + this.acting + this.directing);
  }

  /* Return a description of the attraction. */
  public String category () {
    return "Movie";
  }

}

class Symphony extends Attraction {

  /* Rating parameters. */
  protected int music, playing, conducting;

  /* Constructor. */
  public Symphony (int dur, int m, int p, int c) {
    super(dur);
    this.music = m; this.playing = p; this.conducting = c;
  }

  public int rating () {
    return music + playing + conducting;
  }

  public String category () {
    return "Symphony";
  }

}

/* An opera is a symphony (sort of) with acting and singing.  We override the
   rating method of the superclass to change its behavior for the subclass. */
class Opera extends Symphony {

  /* Rating parameters. */
  private int libretto, singing, acting;

  /* Constructor. */
  public Opera (int dur, int m, int p, int c, int l, int s, int a) {
    super (dur, m, p, c);	// invoke superclass constructor
    this.libretto = l; this.singing = s; this.acting = a;
  }

  /* Calculate rating as a function of the superclass's rating parameters. */
  public int rating () {
    return (super.music + super.playing + super.conducting +
	    this.libretto + this.singing + this.acting);
  }

  public String category () {
    return "Opera";
  }

}

class ProtectedDemo {

  private static String report (String c, int r, int d) {
    return (c + " rating = " + r + ", duration = " + d);
  }

  public static void main (String argv[]) {

    Symphony s = new Symphony(95, 8, 9, 8);
    Movie c = new Movie (90, 6, 7, 4);
    Opera o = new Opera (180, 8, 9, 8, 7, 8, 8);

    System.out.println (report (s.category(), s.rating(), s.duration()));
    System.out.println (report (c.category(), c.rating(), c.duration()));
    System.out.println (report (o.category(), o.rating(), o.duration()));

  }

}
