20-CS-122-001 Computer Science II Spring 2012
Inheritance: Employee Data Base

Virtual functions, classes, inheritance, lists, queues, stacks, applications

   
import java.io.*;
import java.util.*;

class Cell
{
   Object data;
   Cell next;
   
   Cell (Object dat, Cell nxt)
   {
      data = dat;
      next = nxt;
   }
}

class List
{
   Cell head;
   Cell tail;

   List () { head = tail = null; }
   
   Cell next (Cell current) { return current.next; }
   Object objectOf (Cell cell) { return cell.data; }
   
   public void enqueue (Object obj)
   { 
      if (head == null)
      {
         head = tail = new Cell(obj, null);
         return;
      }
      tail.next = new Cell(obj, null);
      tail = tail.next;
   }
}

class Employee
{
   String name;

   Employee() {}
   Employee (String nm) { name = nm; }
   Float computePay() { return new Float(-1); }          
   String getName() { return name; }   
   void  display () {}
   void  setHours(Float hrs) {}
   void  setSales(Float sales) {}
   void  setSalary(Float salary) { System.out.println("NO!"); }   
}

// The EmployeeList class is quite general because it assumes nothing   
// about the Employee objects or derivatives.  It anticipates the         
// need to "find" an object and provides a method for doing that but      
// makes no assumption about how an Employee object is matched with      
// a finding object - it only assumes that a function pointed to by      
// "compare" exists and "compare" has two arguments (Employee object      
// and void *object) and returns a value of 1 if and only if the         
// Employee object and void *object match somehow.  The "compare"         
// pointer is set when the constructor is called.  If "finding" should   
// change in the future, this code doesn't - instead a new "compare"      
// function is passed into the constructor.                              
//
// In addition to "find" this class supplies "findAndExecute" and         
// "executeOnAll" methods.  The "findAndExecute" applied a given         
// function of one argument to an Employee object that is "found" to      
// match a given void *object.  The "executeOnAll" method applies a      
// given function of one argument to every Employee object in the list.   
// As before, no assumptions about Employee objects are made.
class EmployeeList extends List
{
   CompareFunc compare;
   
   // Assign the compare pointer to a given compare function.
   EmployeeList(CompareFunc c) { super(); compare = c; }

   // Return the Employee object which matches the specified    
   // void *object of the argument list based on the "compare"   
   // function.  Return NULL if no match is found.
   Employee find (Object object)
   {
      for (Cell emp = head ; emp != null ; emp = emp.next)
         if (compare.func((Employee)(objectOf(emp)), object) == 1)
            return (Employee)objectOf(emp);
      return null;
   }

   // Find an Employee matching "object" and apply function f.
   void findAndExecute (Object object, FindFunc f, Object arg)
   {
      f.apply(find(object), arg);
   }

   // Apply function f to all Employee objects.
   Object executeOnAll (FindFunc f, Object arg)
   {
      for (Cell emp = head ; emp != null ; emp = emp.next)
         f.apply((Employee)objectOf(emp), arg);
      return arg;
   }
}

class WageEmployee extends Employee
{
   Float rate;
   Float hours;

   WageEmployee(String nm) { super (nm); }
   WageEmployee(String nm, Float r)
   {
      super (nm);
      rate = r;
   }
   
   void setRate (Float r) { rate = r; }
   
   void setHours (Float hrs) { hours = hrs; }
   
   Float getHours() { return hours; }
   
   Float getRate() { return rate; }
   
   Float computePay() { return new Float(rate*hours); }
}

class Programmer extends WageEmployee
{
   Programmer (String nm, Float w) { super (nm, w); }
   
   void display()
   {
      System.out.println("Programmer Name: " + getName() +
           "\tHours: " + getHours() + "\tRate: " + getRate());
   }
}

class SalesPerson extends WageEmployee
{
   Float commission;
   Float SalesMade;
   
   SalesPerson (String nm, Float c)
   {
      super (nm);
      commission = c;
   }
   
   void setCommission(Float comm) { commission = comm; }
   
   void setSales (Float sales) { SalesMade = sales; }
   
   Float computePay() { return new Float(commission*SalesMade); }
   
   void display()
   {
      System.out.println("Salesperson Name: " + getName() +
           "\tCommission: " + commission + "\tSales: " + SalesMade);
   }
}

class Manager extends Employee
{
   Float monthlysalary;
   
   Manager (String nm) { super (nm); }
   
   Manager (String nm, Float w)
   {
      super (nm);
      monthlysalary = w;
   }
   
   Float computePay() { return monthlysalary; }

   void setSalary (Float salary) { monthlysalary = salary; }
   
   void display()
   {
      System.out.println("Manager Name: " + getName() +
           "\tMonthly Salary: " + monthlysalary);
   }
}

interface ManagerInterface
{
   void manager_display();
   Float manager_computePay();
}

class SalesManager extends SalesPerson implements ManagerInterface
{
   Float monthlysalary;
   
   SalesManager(String nm, Float w) { super (nm, w); }
   
   public Float manager_computePay () { return monthlysalary; }
   
   public void manager_display()
   {
      System.out.println("Manager Name: " + getName() +
           "\tMonthly Salary: " + monthlysalary);
   }
   
   Float computePay()
   {
      return computePay() + manager_computePay();
   }
   
   void display()
   {
      super.display();
      manager_display();
   }
}

// These are all the functions that get passed into objects of the      
// EmployeeList class.  The first three are used to set local state      
// of an Employee object (used in findAndExecute(..) method).  The      
// next two are used when something needs to be done to all employees   
// (used in executeOnAll(..) method).  The last one is the compare      
// function.  In this simple example we compare only on "name" but it   
// is possible to compare on other things such as social security #      
// in future versions without changing existing code.
interface FindFunc
{
   void apply (Employee e, Object o);
}

class SetSales implements FindFunc
{
   public void apply (Employee emp, Object sales)
   {
      if (emp != null) ((SalesPerson)emp).setSales((Float)sales);
   }
}

class SetSalary implements FindFunc
{
   public void apply (Employee emp, Object salary)
   {
      if (emp != null) ((Manager)emp).setSalary((Float)salary);
   }
}

class SetHours implements FindFunc
{
   public void apply (Employee emp, Object hrs)
   {
      if (emp != null) ((WageEmployee)emp).setHours((Float)hrs);
   }
}

class Display implements FindFunc
{
   public void apply (Employee emp, Object object)
   {
      if (emp != null) emp.display();
   }
}

class Payroll implements FindFunc
{
   public void apply (Employee emp, Object accum)
   {
      if (emp != null) (Float)accum += emp.computePay();
   }
}

interface CompareFunc
{
   int func (Employee e, Object o);
}

class NameCompare implements CompareFunc
{
   public int func (Employee emp, Object object)
   {
      if (emp != null)
         if (emp.getName() != (String)object) return 1;
      return 0;
   }
}

// The main procedure - create an Employee list, add employees, change
// some values for specific employees, print out the results.
public class emp2
{
   public static void main(String argv[])
   {
      String month[] = { "January", "February", "March", "April", "May",
                         "June", "July", "August", "September", "October",
                         "November", "December" };

      EmployeeList emp = new EmployeeList(new NameCompare());
      emp.enqueue(new SalesManager("Gee", new Float(1000)));
      emp.enqueue(new SalesManager("Gal", new Float(1000)));
      emp.enqueue(new SalesManager("Gem", new Float(1000)));
      emp.enqueue(new SalesPerson("John", new Float(0.03)));
      emp.enqueue(new SalesPerson("Joan", new Float(0.04)));
      emp.enqueue(new SalesPerson("Jack", new Float(0.02)));
      emp.enqueue(new Manager("Fred", new Float(10000)));
      emp.enqueue(new Manager("Frank", new Float(5000)));
      emp.enqueue(new Manager("Florence", new Float(3000)));
      emp.enqueue(new Programmer("Linda", new Float(7)));
      emp.enqueue(new Programmer("Larry", new Float(5)));
      emp.enqueue(new Programmer("Lewis", new Float(3)));

      emp.findAndExecute("Linda", new SetHours(), new Float(35));
      emp.findAndExecute("Larry", new SetHours(), new Float(23));
      emp.findAndExecute("Lewis", new SetHours(), new Float(3));
      emp.findAndExecute("John", new SetSales(), new Float(12000));
      emp.findAndExecute("Joan", new SetSales(), new Float(10000));
      emp.findAndExecute("Jack", new SetSales(), new Float(5000));
      emp.findAndExecute("Gee", new SetSales(), new Float(4000));
      emp.findAndExecute("Gal", new SetSales(), new Float(3000));
      emp.findAndExecute("Gem", new SetSales(), new Float(2000));
      emp.findAndExecute("Gee", new SetSalary(), new Float(1000));
      emp.findAndExecute("Gal", new SetSalary(), new Float(2000));
      emp.findAndExecute("Gem", new SetSalary(), new Float(3000));
      emp.executeOnAll(new Display(), null);
      System.out.println("Payroll: "
           + (Float)emp.executeOnAll(new Payroll(), new Float(0)));
   }
}