Assignment Chef icon Assignment Chef
All English tutorials

Programming lesson

Java OOP Payroll System: Build a Weekly Paycheck Calculator with Employee & Company Classes

Learn to implement a weekly payroll program in Java using object-oriented programming. This tutorial covers the Employee class with private fields, getters/setters, net pay calculation, and the Company class for managing employees. Perfect for COP3330 homework 2.

Java payroll program weekly paycheck calculator Java COP3330 homework 2 Employee class Java Company class Java Java OOP tutorial Java encapsulation example Java ArrayList employee management net pay calculation Java Java toString override Java static field example Java case-insensitive search Java payroll system Java assignment help Java programming for beginners Java object-oriented programming

Introduction: Why Payroll Systems Are a Great OOP Project

Building a weekly payroll program is a classic assignment in Java courses like COP3330. It teaches you how to model real-world entities using classes, encapsulate data with private fields, and implement business logic through methods. In this tutorial, we'll walk through designing the Employee and Company classes step by step. Think of it like creating a mini HR app—just like how modern payroll software (e.g., Gusto, ADP) handles millions of employees, you'll handle a small team.

Understanding the Problem: What the Assignment Asks

You need to implement a simple weekly payroll program. Input includes the employee's full name, employee ID (String), hours worked (double), hourly rate (double), and a 6% income tax. The program calculates gross pay (hours * rate), deductions, and net pay. The output is a formatted paycheck. You must create an Employee class with private fields: fullName, employeeNumber, payRate, and hoursWorked. It should have a constructor, getters/setters, a toString() method, a private netPay() method, and a printCheck() method. Then, a Company class manages a list of employees with methods like hire(), printEmployees(), searchByName(), etc.

Step 1: Designing the Employee Class

Start by declaring the private fields. In Java, encapsulation is key—fields are private so they can't be accessed directly from outside the class.

public class Employee {
    private String fullName;
    private String employeeNumber;
    private double payRate;
    private double hoursWorked;
    // ... methods
}

Next, add a constructor that initializes all fields:

public Employee(String fullName, String employeeNumber, double payRate, double hoursWorked) {
    this.fullName = fullName;
    this.employeeNumber = employeeNumber;
    this.payRate = payRate;
    this.hoursWorked = hoursWorked;
}

Add getters and setters for each field. For example:

public String getFullName() { return fullName; }
public void setFullName(String fullName) { this.fullName = fullName; }

Override toString() to return a formatted string like [js1200/John Smith, 36 Hours @ 10.5 per hour].

@Override
public String toString() {
    return "[" + employeeNumber + "/" + fullName + ", " + hoursWorked + " Hours @ " + payRate + " per hour]";
}

Now implement the private netPay() method. Gross pay = hoursWorked * payRate. Net pay = gross pay - 6% tax.

private double netPay() {
    double grossPay = hoursWorked * payRate;
    double tax = grossPay * 0.06;
    return grossPay - tax;
}

Finally, the printCheck() method uses netPay() to display the paycheck. Use System.out.printf() for formatting.

public void printCheck() {
    double grossPay = hoursWorked * payRate;
    double tax = grossPay * 0.06;
    double net = netPay();
    System.out.println("—————————————————————————");
    System.out.println("Employee's name: " + fullName);
    System.out.println("Employee's number: " + employeeNumber);
    System.out.println("Hourly rate of pay: " + payRate);
    System.out.println("Hours worked: " + hoursWorked);
    System.out.println("Total Gross Pay: $" + String.format("%.2f", grossPay));
    System.out.println("Deductions");
    System.out.println("Tax (6 %): $" + String.format("%.2f", tax));
    System.out.println("Net Pay: $" + String.format("%.2f", net) + " Dollars");
    System.out.println("—————————————————————————");
}

Step 2: Building the Company Class

The Company class manages an ArrayList<Employee> and has a company name and tax ID. It includes methods to hire employees (ensuring unique employee numbers), print company info, print all employees, count employees by salary, search by name (case-insensitive), reverse the employee list, delete employees by salary, and print a check for a specific employee number.

Start with the fields and constructor:

import java.util.ArrayList;

public class Company {
    private ArrayList<Employee> employeeList;
    private String companyName;
    private static String companyTaxId;

    public Company() {
        employeeList = new ArrayList<>();
        companyName = "People's Place";
        companyTaxId = "v1rtua7C0mpan1";
    }

    // static getters and setters for companyTaxId
    public static String getCompanyTaxId() { return companyTaxId; }
    public static void setCompanyTaxId(String id) { companyTaxId = id; }

    // getters and setters for companyName
    public String getCompanyName() { return companyName; }
    public void setCompanyName(String name) { this.companyName = name; }
}

Implement hire() – it should check if an employee with the same number already exists. If not, add to the list and return true; else return false.

public boolean hire(Employee employee) {
    for (Employee e : employeeList) {
        if (e.getEmployeeNumber().equals(employee.getEmployeeNumber())) {
            return false; // duplicate employee number
        }
    }
    employeeList.add(employee);
    return true;
}

printCompanyInfo() prints the company name, tax ID, and current number of employees.

public void printCompanyInfo() {
    System.out.println("Company: " + companyName);
    System.out.println("Tax ID: " + companyTaxId);
    System.out.println("Number of employees: " + employeeList.size());
}

printEmployees() prints each employee using their toString() method.

public void printEmployees() {
    for (Employee e : employeeList) {
        System.out.println(e);
    }
}

countEmployees(double maxSalary) returns the count of employees whose gross pay (hours * rate) is less than maxSalary.

public int countEmployees(double maxSalary) {
    int count = 0;
    for (Employee e : employeeList) {
        if (e.getHoursWorked() * e.getPayRate() < maxSalary) {
            count++;
        }
    }
    return count;
}

searchByName(String fullName) does a case-insensitive search.

public boolean searchByName(String fullName) {
    for (Employee e : employeeList) {
        if (e.getFullName().equalsIgnoreCase(fullName)) {
            return true;
        }
    }
    return false;
}

reverseEmployees() reverses the order of the list.

public void reverseEmployees() {
    for (int i = 0; i < employeeList.size() / 2; i++) {
        Employee temp = employeeList.get(i);
        int j = employeeList.size() - 1 - i;
        employeeList.set(i, employeeList.get(j));
        employeeList.set(j, temp);
    }
}

deleteEmployeesBySalary(double targetSalary) removes all employees whose gross pay equals targetSalary.

public void deleteEmployeesBySalary(double targetSalary) {
    ArrayList<Employee> toRemove = new ArrayList<>();
    for (Employee e : employeeList) {
        if (e.getHoursWorked() * e.getPayRate() == targetSalary) {
            toRemove.add(e);
        }
    }
    employeeList.removeAll(toRemove);
}

printCheck(String employeeNumber) finds the employee by number and calls their printCheck() method, or prints "NO SUCH EMPLOYEE EXISTS".

public void printCheck(String employeeNumber) {
    for (Employee e : employeeList) {
        if (e.getEmployeeNumber().equals(employeeNumber)) {
            e.printCheck();
            return;
        }
    }
    System.out.println("NO SUCH EMPLOYEE EXISTS");
}

Step 3: Putting It All Together (DriverClass)

Your DriverClass should contain all three classes in one file. The provided driver code tests the functionality. Make sure you follow the exact method signatures and naming. Here's a snippet of what the driver does:

public class DriverClass {
    public static void main(String[] args) {
        Employee e = new Employee("Erika T. Jones", "ej789", 100.0, 1.0);
        System.out.println(e);
        e.printCheck();
        Company company = new Company();
        company.hire(new Employee("Saeed Happy", "sh895", 2, 200));
        company.hire(e);
        company.printCompanyInfo();
        // ... rest of the driver
    }
}

Common Pitfalls and Tips

  • Unique employee numbers: In hire(), always check for duplicates. Use equals() on the employee number strings.
  • Case-insensitive search: Use equalsIgnoreCase() for name comparison.
  • Static tax ID: The companyTaxId is static, meaning it's shared across all Company instances. Use static getters/setters.
  • Formatting: Use String.format("%.2f", value) to display two decimal places for currency.
  • Private netPay(): Since it's private, it can only be called from within the Employee class. The printCheck() method calls it.

Real-World Analogy: Like a Gaming Leaderboard

Think of the Company class as a gaming platform that manages players (employees). Each player has a username (employee number), hours played (hours worked), and skill level (pay rate). The platform can add new players, search for them, reverse the leaderboard, and remove players with a certain score. This is similar to how games like Fortnite or League of Legends manage player stats.

Conclusion

You've now built a complete payroll system using Java OOP. This assignment covers encapsulation, constructors, methods, ArrayList manipulation, and string formatting. Practice by adding extra features like overtime pay or different tax brackets. Good luck with your COP3330 homework!