20-CS-4003-001 Organization of Programming Languages Fall 2017
Lab Assignment 1

Lambda calculus, Type theory, Formal semantics, Program analysis

Virtual functions, abstract classes

due: 1 September, 2017 (submit instructions: here)

Rationale:
    This is a simple warm-up exercise.
 
Important:
    You should not solve this by thinking this is a stand-alone, one-shot problem. Think of this as a way to develop a class hierarchy that can be placed in a library and never be modified afterward to accommodate new user classes that might be developed. So, in Wages.java we give you a class Employee, and subclasses WageEmployee, Manager, Programmer, Salesperson, and SalesManager and ask you to write an EmployeeList container class that implements methods for the maintenance of a database of Employee objects. The properties that the EmployeeList should have are described below. Your code should be designed in such a way that is does not break by adding, for example, a President class, or a part-time Worker Class, or a Student co-op class, or any other class of object that might be derived from one of the subclasses of the Employee class and added to the EmployeeList database. This is an exercise in polymorphism. Virtual functions are one means that C++ and Java have to support polymorphism.
 
Lab Problem:
Create a class called EmployeeList that is a container of objects of the following kind:
abstract class Employee {
   String name;
	   
   Employee() {}
   Employee (String nm) { name = nm; }
   abstract double computePay();
   void display () {}
   void setHours(double hrs) {}
   void setSales(double sales) {}
   void setSalary(double salary) { System.out.println("NO!"); }
}
This class and subclasses of this class are contained in file Wages.java, which compiles correctly without the EmployeeList class. You will add your implementation of the EmployeeList class to this file, uncomment the code at the bottom of the file, and maybe modify some of the existing code to see it run.

The EmployeeList class should provide the following methods: Employee find (String nm) that returns an object in the container whose name matches nm, or null if no such Employee is in the container; void setHours(String nm, double hrs) that invokes setHours(hrs) on the employee in the container whose name matches nm; void setSalary(String nm, double salary) that invokes setSalary(salary) on the employee in the container whose name matches nm; void setSales(String nm, double sales) that invokes setSales(sales) on the employee in the container whose name matches nm; double payroll() that computes the total payroll of all Employee objects in the container using the computePay() method of each; and void display() which invokes display() of each employee in the container.

The following kinds of objects are derived from the Employee class:

  1. WageEmployee: has double rate, hours defined. There are two constructors: one takes a name as argument and the other takes name and rate as arguments. Pay is computed by multiplying hours and rate. Low on the totem pole and its rank cannot be changed.
  2. Manager: has double monthlysalary defined. Has two constructors: one with no arguments, one with name and salary as arguments. Pay is just monthlysalary.
The following kinds of objects extend WageEmployee:
  1. Programmer: has one constructor with arguments name and rate. Pay is computed from the super class.
  2. SalesPerson: has double commission, salesMade defined. Has one constructor with name and commission as arguments. Pay is computed by multiplying commission and salesMade.
One other employee type is the following:
  1. SalesManager: Has one constructor with arguments name and commission. Pay is computed by adding the result of computing pay as though the employee is of type SalesPerson to the result of computing pay as though the employee is of type Manager.
You must figure out what should be inherited and what needs to be interfaced. The diagram below shows the class structure.

Try your code on this:

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

emp.setHours("Linda", 35);
emp.setHours("Larry", 23);
emp.setHours("Lewis", 3);
emp.setSales("John", 12000);
emp.setSales("Joan", 10000);
emp.setSales("Jack", 5000);
emp.setSales("Gee", 4000);
emp.setSales("Gal", 3000);
emp.setSales("Gem", 2000);
emp.setSalary("Gee", 1000);
emp.setSalary("Gal", 2000);
emp.setSalary("Gem", 3000);
emp.display();
System.out.println("Payroll: "+emp.payroll());
 
Sample Output:
Name: Gee       Commission: 1000.0      Sales: 4000.0
Name: Gee       Monthly Salary: 1000.0
Name: Gal       Commission: 1000.0      Sales: 3000.0
Name: Gal       Monthly Salary: 2000.0
Name: Gem       Commission: 1000.0      Sales: 2000.0
Name: Gem       Monthly Salary: 3000.0
Name: John      Commission: 0.03        Sales: 12000.0
Name: Joan      Commission: 0.04        Sales: 10000.0
Name: Jack      Commission: 0.02        Sales: 5000.0
Name: Fred      Monthly Salary: 10000.0
Name: Frank     Monthly Salary: 5000.0
Name: Florence  Monthly Salary: 3000.0
Name: Linda     Hours: 35.0     Rate: 7.0
Name: Larry     Hours: 23.0     Rate: 5.0
Name: Lewis     Hours: 3.0      Rate: 3.0

SalesManager: Gee 4001000.0
SalesManager: Gal 3002000.0
SalesManager: Gem 2003000.0
Payroll: 9025229.0