Assignment Chef icon Assignment Chef
All English tutorials

Programming lesson

Building a Person Management System: Mastering Inheritance and Abstract Classes in Java

Learn how to implement inheritance, abstract classes, and method overriding in Java by building a Person Management System similar to a COP3330 final project. Step-by-step tutorial with timely examples from AI and gaming.

Java inheritance tutorial abstract class Java example method overriding Java COP3330 final project Java OOP project person management system Java Java exception handling ID validation regex Java Java ArrayList persons Java tuition invoice calculation Java inheritance hierarchy Java abstract method print Java getters setters Java duplicate ID check Java programming assignment help Java class design patterns

Introduction

In the world of Java programming, mastering inheritance and abstract classes is like leveling up in a game—it unlocks powerful abilities to organize and reuse code. Whether you're building a management system for a university or a character class hierarchy for the next hit RPG, these concepts are essential. In this tutorial, we'll walk through creating a Person Management System similar to the COP3330 final project, using inheritance, abstract classes, and method overriding. We'll keep it timely by drawing parallels to AI models and gaming mechanics. By the end, you'll have a solid understanding of how to design class hierarchies that are both flexible and maintainable.

Understanding the Problem

The assignment requires a system that manages students, faculty, and staff. All are persons, but each has unique attributes. Students have a GPA and credit hours; faculty and staff are employees with departments and statuses. The key is to avoid code duplication by using inheritance. Think of it like a character in a game: a base class Person holds common attributes (name, ID), while subclasses add specific traits. In AI, you might have a base Model class with subclasses LLM and VisionModel. The same principle applies here.

Setting Up the Base Class: Person

We start with an abstract class Person. Abstract classes cannot be instantiated; they serve as blueprints. Our Person will have private fields for fullName and id, along with getters, setters, and constructors. It will also declare an abstract method print() that subclasses must override. This is like a base class in a game that defines a method attack() but leaves the implementation to subclasses like Warrior or Mage.

public abstract class Person {
    private String fullName;
    private String id;

    public Person(String fullName, String id) {
        this.fullName = fullName;
        this.id = id;
    }

    // Getters and setters
    public String getFullName() { return fullName; }
    public void setFullName(String fullName) { this.fullName = fullName; }
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }

    public abstract void print();
}

Adding the Employee Abstract Class

Next, we create an abstract class Employee that extends Person. It will hold common employee attributes like department and status. This is similar to a Character class in a game that extends Entity and adds health points. In our system, both faculty and staff share these fields, so we put them here. Note that Employee itself is abstract, so it cannot be instantiated.

public abstract class Employee extends Person {
    private String department;
    private String status; // part-time or full-time

    public Employee(String fullName, String id, String department, String status) {
        super(fullName, id);
        this.department = department;
        this.status = status;
    }

    // Getters and setters
    public String getDepartment() { return department; }
    public void setDepartment(String department) { this.department = department; }
    public String getStatus() { return status; }
    public void setStatus(String status) { this.status = status; }
}

Implementing Student Class

The Student class extends Person directly (since students are not employees). It adds gpa and creditHours. The print() method will generate a tuition invoice. For example, if a student takes 7 credit hours at $236.45 per hour plus a $52 fee, the total is calculated. This is like a character sheet in an RPG that displays stats and calculates damage.

public class Student extends Person {
    private double gpa;
    private int creditHours;

    public Student(String fullName, String id, double gpa, int creditHours) {
        super(fullName, id);
        this.gpa = gpa;
        this.creditHours = creditHours;
    }

    @Override
    public void print() {
        double total = creditHours * 236.45 + 52;
        System.out.println("Here is the tuition invoice for " + getFullName() + ":");
        System.out.println("-----------------------------------------------");
        System.out.println(getFullName() + " " + getId());
        System.out.println("Credit Hours: " + creditHours + " ($236.45/credit hour)");
        System.out.println("Fees: $52");
        System.out.println("Total payment: $" + total);
        System.out.println("-----------------------------------------------");
    }
}

Implementing Faculty and Staff Classes

Both extend Employee. Faculty might have a rank, while Staff has a role. For simplicity, we'll keep them minimal. The print() method displays their information. This is like subclasses of a base class in a game that override a method to show different stats.

public class Faculty extends Employee {
    public Faculty(String fullName, String id, String department, String status) {
        super(fullName, id, department, status);
    }

    @Override
    public void print() {
        System.out.println("-----------------------------------------------");
        System.out.println(getFullName() + " " + getId());
        System.out.println("Department: " + getDepartment());
        System.out.println("Status: " + getStatus());
        System.out.println("-----------------------------------------------");
    }
}

public class Staff extends Employee {
    public Staff(String fullName, String id, String department, String status) {
        super(fullName, id, department, status);
    }

    @Override
    public void print() {
        System.out.println("-----------------------------------------------");
        System.out.println(getFullName() + " " + getId());
        System.out.println("Department: " + getDepartment());
        System.out.println("Status: " + getStatus());
        System.out.println("-----------------------------------------------");
    }
}

ID Validation and Duplicate Checking

IDs must follow the pattern LetterLetterDigitDigitDigitDigit (e.g., ju1254). We'll use a regex: [a-zA-Z]{2}\d{4}. Also, no two persons can have the same ID. This is like checking for duplicate usernames in a social media app. We'll store all persons in an ArrayList<Person> and validate before adding.

public boolean isValidId(String id) {
    return id.matches("[a-zA-Z]{2}\\d{4}");
}

public boolean isDuplicateId(String id) {
    for (Person p : persons) {
        if (p.getId().equals(id)) return true;
    }
    return false;
}

Putting It All Together: The Main Program

The main class FinalProject will have a menu-driven loop. Users can enter information, print invoices, and delete persons. Exception handling is crucial—use try-catch for input mismatches and custom exceptions if needed. This is like a game's main menu where you choose actions.

import java.util.*;

public class FinalProject {
    private static ArrayList<Person> persons = new ArrayList<>();
    private static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) {
        System.out.println("Welcome to my Personal Management Program");
        int choice;
        do {
            System.out.println("Choose one of the options:");
            System.out.println("1- Enter the information of a faculty");
            System.out.println("2- Enter the information of a student");
            System.out.println("3- Print tuition invoice for a student");
            System.out.println("4- Print faculty information");
            System.out.println("5- Enter the information of a staff member");
            System.out.println("6- Print the information of a staff member");
            System.out.println("7- Delete a person");
            System.out.println("8- Exit Program");
            System.out.print("Enter your selection: ");
            try {
                choice = scanner.nextInt();
                scanner.nextLine(); // consume newline
                switch (choice) {
                    case 1: addFaculty(); break;
                    case 2: addStudent(); break;
                    case 3: printTuitionInvoice(); break;
                    case 4: printFacultyInfo(); break;
                    case 5: addStaff(); break;
                    case 6: printStaffInfo(); break;
                    case 7: deletePerson(); break;
                    case 8: System.out.println("Exiting..."); break;
                    default: System.out.println("Invalid entry- please try again");
                }
            } catch (InputMismatchException e) {
                System.out.println("Invalid entry- please try again");
                scanner.nextLine(); // clear buffer
                choice = 0;
            }
        } while (choice != 8);
    }

    // Methods for each case...
}

Trend Connection: AI and Gaming

Just as AI models like GPT-4 have base classes with specialized subclasses (e.g., TextModel, ImageModel), our system uses inheritance to avoid repeating code. In gaming, consider the Character class in a game like Valorant; each agent (Jett, Phoenix) inherits common attributes but overrides abilities. This design pattern is everywhere—from school projects to production systems.

Conclusion

By building this Person Management System, you've learned to use inheritance, abstract classes, and method overriding in Java. These concepts are foundational for designing scalable and maintainable software. Whether you're creating a university system, an AI framework, or a game, the principles remain the same. Keep practicing, and soon you'll be designing complex hierarchies with ease. Remember: the key is to identify what's common and what's specific, then let inheritance do the heavy lifting.

For more tutorials, check out our other guides on Java OOP, exception handling, and data structures. Happy coding!