//Employee.java
  // Abstract base class Employee
  public abstract class Employee {
     private String firstName;
     private String lastName;
     // Constructor
     public Employee(String first, String last )
     {
        firstName = first;
        lastName = last;
     }
     // Return the first name
     public String getFirstName() { return firstName; }
     // Return the last name
     public String getLastName() { return lastName; }
     public String toString() { return firstName + ' ' + lastName; }
     // Abstract method that must be implemented for each 
     // derived class of Employee from which objects 
     // are instantiated.
     public abstract double earnings();
  } 
  --------------------------
  
  //Boss.java
  // Boss class derived from Employee
  public final class Boss extends Employee {
     private double weeklySalary; 
     // Constructor for class Boss
     public Boss( String first, String last, double s)
     {
        super( first, last );  // call superclass constructor
        setWeeklySalary(s );
     }
     // Set the Boss's salary
     public void setWeeklySalary( double s )
        { weeklySalary = ( s > 0 ? s : 0 ); }
     // Get the Boss's pay
     public double earnings() { return weeklySalary; }
     // Print the Boss's name 
     public String toString() 
     { return "Boss: " + super.toString();}
  }
 ----------------------------------
  //PieceWorker.java
  // PieceWorker class derived from Employee
  public final class PieceWorker extends Employee {
     private double wagePerPiece; // wage per piece output
     private int quantity;        // output for week
     // Constructor for class PieceWorker
     public PieceWorker(String first, String last, double w, int q )
     {
        super( first, last );  // call superclass constructor
        setWage( w );
        setQuantity( q);}
     // Set the wage
     public void setWage( double w ) 
        { wagePerPiece = ( w > 0 ? w : 0 ); }
     // Set the number of items output
     public void setQuantity( int q ) 
        { quantity = ( q > 0 ? q : 0 ); }
  // Determine the PieceWorker's earnings
     public double earnings()
        { return quantity * wagePerPiece; }
     public String toString()
        { return "Piece worker: " + super.toString();}
  }  
  -----------------------------
  //CommissionWorker.java
  // CommissionWorker class derived from Employee
  public final class CommissionWorker extends Employee {
     private double salary;      // base salary per week
     private double commission;  // amount per item sold
     private int quantity;       // total items sold for week
     // Constructor for class CommissionWorker
     public CommissionWorker( String first, String last,
                              double s, double c, int q)
     {super( first, last );  // call superclass constructor
        setSalary( s );
        setCommission( c);
        setQuantity( q);
     }
     // Set CommissionWorker's weekly base salary
     public void setSalary( double s )
        { salary = ( s > 0 ? s : 0 ); }
     // Set CommissionWorker's commission
     public void setCommission( double c ) 
        { commission = ( c > 0 ? c : 0 ); }
     // Set CommissionWorker's quantity sold
     public void setQuantity( int q )
       { quantity = ( q > 0 ? q : 0 ); }
     
     // Determine CommissionWorker's earnings
     public double earnings()
        { return salary + commission * quantity; }
     // Print the CommissionWorker's name 
     public String toString() 
     { return "Commission worker: " + super.toString();}
  }
  ---------------------------
  //HourlyWorker.java
  // Definition of class HourlyWorker
  public final class HourlyWorker extends Employee {
     private double wage;   // wage per hour
     private double hours;  // hours worked for week
     // Constructor for class HourlyWorker
     public HourlyWorker( String first, String last, 
                          double w, double h )
     {
        super( first, last );   // call superclass constructor
        setWage( w );
        setHours( h );
     }
     // Set the wage
     public void setWage( double w )
        { wage = ( w > 0 ? w : 0 ); }
     // Set the hours worked
     public void setHours( double h )
        { hours = ( h >= 0 && h < 168 ? h : 0 ); }
     // Get the HourlyWorker's pay
     public double earnings() { return wage * hours; }
     public String toString() {return "Hourly worker: " + super.toString();}
  }
  -----------------------------
  //Test.java
  // Driver for Employee hierarchy
  import java.text.DecimalFormat;
  public class Test {
     public static void main( String args[] )
     {
        Employee ref;  // superclass reference
        String output = "";
        Boss b = new Boss( "John", "Smith", 800.00 );
        CommissionWorker c = new CommissionWorker( "Sue", "Jones", 400.0, 3.0, 150);
        PieceWorker p = new PieceWorker( "Bob", "Lewis", 2.5, 200 );
        HourlyWorker h = new HourlyWorker( "Karen", "Price", 13.75, 40 );
        DecimalFormat precision2 = new DecimalFormat( "0.00" );
        ref = b;  // Employee reference to a Boss 
        output += ref.toString() + " earned $" +
                  precision2.format( ref.earnings() ) + "\n" +
                  b.toString() + " earned $" +
                  precision2.format( b.earnings() ) + "\n";
        ref = c;  // Employee reference to a CommissionWorker
        output += ref.toString() + " earned $" +
                  precision2.format( ref.earnings() ) + "\n" +
                  c.toString() + " earned $" +
                  precision2.format( c.earnings() ) + "\n";
        ref = p;  // Employee reference to a PieceWorker
        output += ref.toString() + " earned $" +
                  precision2.format( ref.earnings() ) + "\n" +
                  p.toString() + " earned $" +
                  precision2.format( p.earnings() ) + "\n";
        ref = h;  // Employee reference to an HourlyWorker
        output += ref.toString() + " earned $" +
                  precision2.format( ref.earnings() ) + "\n" +
                  h.toString() + " earned $" +
                  precision2.format( h.earnings() ) + "\n";
        System.out.println("Demonstrating Polymorphism\n" + output);
     }
  }  
  
  -----------------------------------------------------
  //   Shape.java
  // Definition of abstract base class Shape
  public abstract class Shape extends Object {
     public double area() { return 0.0; }
     public double volume() { return 0.0; }
     public abstract String getName();
  }   
 ----------------------
  //Point.java
  // Definition of class Point
  public class Point extends Shape {
     protected int x, y;
    // coordinates of the Point
     // no-argument constructor
     public Point() {setPoint( 0, 0 ); }
     // constructor
     public Point( int a, int b ) { setPoint( a, b ); }
     // Set x and y coordinates of Point
     public void setPoint( int a, int b )
     {
        x = a;
        y = b;
     }
     // get x coordinate
     public int getX() {
    return x; }
     // get y coordinate
     public int getY() {
    return y; }
     // convert the point into a String representation
     public String toString() 
        { return "[" + x + ", " + y + "]"; }
     // return the class name 
     public String getName() { return "Point"; }
  }
  ------------------------
  
  //Circle.java
  // Definition of class Circle
  public class Circle extends Point {  // inherits from Point
     protected double radius;
     // no-argument constructor
     public Circle()
     {
        // implicit call to superclass constructor here
        setRadius( 0);  
     }
     // Constructor
     public Circle(double r, int a, int b )
     {
        super( a, b);  // call the superclass constructor
        setRadius( r );  
     }
     // Set radius of Circle
     public void setRadius( double r )
     { radius = ( r >= 0 ? r : 0 );
    }
     // Get radius of Circle
     public double getRadius() { return radius; }
     // Calculate area of Circle
     public double area() { return Math.PI * radius * radius; }
     // convert the Circle to a String
     public String toString()
        { return "Center = " + super.toString() + "; Radius = " + radius; }
     // return the class name
     public String getName() { return "Circle"; }
  }
  
  ---------------------------------
  //Cylinder.java
  // Definition of class Cylinder
  public class Cylinder extends Circle {
     protected double height;  // height of Cylinder
     // no-argument constructor
     public Cylinder()      
     {
        // implicit call to superclass constructor here
        setHeight( 0 );
     }
     // constructor
     public Cylinder(double h, double r, int a, int b )      
     {
        super( r, a, b);   // call superclass constructor
        setHeight( h );
     }
     // Set height of Cylinder
     public void setHeight( double h )
        { height = ( h >= 0 ? h : 0 ); }
     // Get height of Cylinder
     public double getHeight() { return height; }
     // Calculate area of Cylinder (i.e., surface area)
     public double area()
     {  return 2 * super.area() + 2 * Math.PI * radius * height;}
     // Calculate volume of Cylinder
     public double volume() { return super.area() * height; }
     // Convert a Cylinder to a String
     public String toString()
        { return super.toString() + "; Height = " + height; }
     // Return the class name
     public String getName() { return "Cylinder"; }
}
  
  ---------------------------------------------
  //Test.java
  // Driver for point, circle, cylinder hierarchy
  import java.text.DecimalFormat;
  public class Test {
     public static void main( String args[] )
     {
        Point point = new Point( 7, 11 );          
        Circle circle = new Circle( 3.5, 22, 8 );  
        Cylinder cylinder = new Cylinder( 10, 3.3, 10, 10 );
        Shape arrayOfShapes[];
        arrayOfShapes = new Shape[ 3 ];
        // note that the above creates an array; normally the initialization step might call
        // a constructor of the class Shape, e.g., arrayOfShapes[0] = new Shape();
        // however in this case we can't do this because Shape is an abstract class

        // aim arrayOfShapes[0] at subclass Point object
        arrayOfShapes[ 0 ] = point;
        // aim arrayOfShapes[1] at subclass Circle object
        arrayOfShapes[ 1 ] = circle;
        // aim arrayOfShapes[2] at subclass Cylinder object
        arrayOfShapes[ 2 ] = cylinder;  
        String output = point.getName() + ": " + point.toString() + "\n" +
           circle.getName() + ": " + circle.toString() + "\n" +
           cylinder.getName() + ": " + cylinder.toString();
        DecimalFormat precision2 = new DecimalFormat( "0.00" );
        // Loop through arrayOfShapes and print the name, area, and volume of each object.
        for ( int i = 0; i < arrayOfShapes.length; i++ ) {
           output += "\n\n" +
              arrayOfShapes[ i ].getName() + ": " +
              arrayOfShapes[ i ].toString() + "\nArea = " +
              precision2.format( arrayOfShapes[ i ].area() ) + "\nVolume = " +
              precision2.format( arrayOfShapes[ i ].volume() );
        }
        System.out.println("Demonstrating Polymorphism\n" + output);
        }
  }
  
  --------------------------------------
  //Shape.java
  // Definition of interface Shape
  public interface Shape {
     public abstract double area();
     public abstract double volume();
     public abstract String getName();   
 }
 ------------------
 
  //Point.java
  // Definition of class Point
  public class Point extends Object implements Shape {
     protected int x, y;
    // coordinates of the Point
     // no-argument constructor
     public Point() {setPoint( 0, 0 ); }
     // constructor 
     public Point( int a, int b ) { setPoint( a, b ); }
     // Set x and y coordinates of Point
     public void setPoint( int a, int b )
     {
        x = a;
        y = b;
     }
     // get x coordinate
     public int getX() {return x; }
     // get y coordinate
     public int getY() {return y; }
     // convert the point into a String representation
     public String toString() 
        { return "[" + x + ", " + y + "]"; }
     // return the area 
     public double area() { return 0.0; }
     // return the volume 
     public double volume() { return 0.0; }
     // return the class name
     public String getName() { return "Point"; }
}
  
  ------------------------
  //Circle.java
  // Definition of class Circle
  public class Circle extends Point {  // inherits from Point
     protected double radius;
     // no-argument constructor
     public Circle()
     {
        // implicit call to superclass constructor here
        setRadius( 0 );  
     }
     // Constructor
     public Circle(double r, int a, int b )
     {
        super( a, b);  // call the superclass constructor
        setRadius( r);  
     }
     // Set radius of Circle
     public void setRadius( double r ) { radius = ( r >= 0 ? r : 0 ); }
     // Get radius of Circle
     public double getRadius() { return radius; }
     // Calculate area of Circle
     public double area() { return Math.PI * radius * radius; }
     // convert the Circle to a String
     public String toString()
        { return "Center = " + super.toString() + "; Radius = " + radius; }
     // return the class name
     public String getName() { return "Circle"; }
  }
  
  -------------------------
  //Cylinder.java
  // Definition of class Cylinder
  public class Cylinder extends Circle {
     protected double height;  // height of Cylinder
     // no-argument constructor
     public Cylinder()      
     { // implicit call to superclass constructor here
        setHeight( 0 );
     }
     // constructor
     public Cylinder(double h, double r, int a, int b )      
     {
        super( r, a, b);   // call superclass constructor
        setHeight( h );
     }
     // Set height of Cylinder
     public void setHeight( double h )
        { height = ( h >= 0 ? h : 0 ); }
     // Get height of Cylinder
     public double getHeight() { return height; }
     // Calculate area of Cylinder (i.e., surface area)
     public double area()
     { return 2 * super.area() + 2 * Math.PI * radius * height;
     }
     // Calculate volume of Cylinder
     public double volume() { return super.area() * height; }
     // Convert a Cylinder to a String
     public String toString()
        { return super.toString() + "; Height = " + height; }
     // Return the class name
     public String getName() { return "Cylinder"; }
  }
  ---------------------
  
  //Test.java
  // Driver for point, circle, cylinder hierarchy
  import java.text.DecimalFormat;
  public class Test {
     public static void main( String args[] )
     {
        Point point = new Point( 7, 11 );          
        Circle circle = new Circle( 3.5, 22, 8 );  
        Cylinder cylinder = new Cylinder( 10, 3.3, 10, 10 ); 
        Shape arrayOfShapes[];
        arrayOfShapes = new Shape[ 3 ];
        // aim arrayOfShapes[0] at subclass Point object 
        arrayOfShapes[ 0 ] = point;
        // aim arrayOfShapes[1] at subclass Circle object
        arrayOfShapes[ 1 ] = circle;
        // aim arrayOfShapes[2] at subclass Cylinder object
        arrayOfShapes[ 2 ] = cylinder;  
        String output = 
           point.getName() + ": " + point.toString() + "\n" +
           circle.getName() + ": " + circle.toString() + "\n" +
           cylinder.getName() + ": " + cylinder.toString();
        DecimalFormat precision2 = new DecimalFormat( "0.00" );
        // Loop through arrayOfShapes and print the name,
        // area, and volume of each object.
        for ( int i = 0; i < arrayOfShapes.length; i++ ) {
           output += "\n\n" +
              arrayOfShapes[ i ].getName() + ": " +
              arrayOfShapes[ i ].toString() +
             "\nArea = " +
              precision2.format( arrayOfShapes[ i ].area() ) +
             "\nVolume = " +
              precision2.format( arrayOfShapes[ i ].volume() );
        }
        System.out.println("Demonstrating Polymorphism\n" + output);
       }
  }
  

Revised: December 3, 2008