Java Object-Oriented Student Management System
This document presents a foundational Java application demonstrating object-oriented programming (OOP) principles through a simple university student management system. It showcases inheritance, polymorphism, and class design to manage different types of students: undergraduates, graduates, and alumni.
Core Class Definitions
The system is built upon a hierarchy of classes, starting with an abstract Student class, which defines common attributes and behaviors for all student types. Specific student categories then extend this base class, implementing or overriding methods as needed.
The Student
Abstract Class
The Student
class serves as the abstract base for all student types. It encapsulates common properties like name
and id
, and defines abstract methods that must be implemented by its subclasses, ensuring a consistent interface across different student categories. It also includes a placeholder save
method for data persistence.
public abstract class Student {
protected String name;
protected int id;
public Student(String name, int id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public int getId() {
return id;
}
public abstract String type(); // Returns the type of student (e.g., "undergraduate", "graduate", "alumni")
public abstract String toString(); // Provides a string representation of the student object
// Placeholder for saving student data. In a real application, this would handle file I/O.
public void save(String filename) {
System.out.println("Attempting to save data for " + name + " (ID: " + id + ") to " + filename + ".");
}
}
The Undergraduate
Class
The Undergraduate
class extends Student
, adding specific attributes like graduationYear
and a list of courses
. It implements methods relevant to undergraduate students, such as displaying their level and registering for courses.
class Undergraduate extends Student {
private int graduationYear;
private ArrayList<String> courses;
public Undergraduate(String name, int id, int graduationYear) {
super(name, id);
this.graduationYear = graduationYear;
this.courses = new ArrayList<>();
}
public void displayStudentLevel() {
System.out.println(name + " is an undergraduate student.");
}
public void registerCourses() {
Random rand = new Random();
int numCourses = rand.nextInt(5) + 1; // Registers between 1 and 5 courses
for (int i = 1; i <= numCourses; i++) {
courses.add("Course" + i);
}
System.out.println(name + " whose ID is: " + id + " started at AUS in " + graduationYear + ".");
System.out.println(name + " is registered in " + numCourses + " course(s).");
}
@Override
public String type() {
return "undergraduate";
}
@Override
public String toString() {
return name + " Undergraduate ID: " + id + " Grad Year: " + graduationYear;
}
}
The Graduate
Class
Similar to Undergraduate
, the Graduate
class extends Student
. It includes additional information such as whether the student completed their undergraduate studies at the same university (sameUniversity
). It also provides its own implementations for displaying student level and course registration.
class Graduate extends Student {
private int graduationYear;
private boolean sameUniversity;
private ArrayList<String> courses;
public Graduate(String name, int id, int graduationYear, boolean sameUniversity) {
super(name, id);
this.graduationYear = graduationYear;
this.sameUniversity = sameUniversity;
this.courses = new ArrayList<>();
}
public void displayStudentLevel() {
System.out.println(name + " is a graduate student." +
(sameUniversity ? " They also did their undergraduate studies at the same university." :
" However, they did their undergraduate studies at a different university."));
}
public void registerCourses() {
Random rand = new Random();
int numCourses = rand.nextInt(5) + 1; // Registers between 1 and 5 courses
for (int i = 1; i <= numCourses; i++) {
courses.add("Course" + i);
}
System.out.println(name + " whose ID is: " + id + " started at AUS in " + graduationYear + ".");
System.out.println(name + " is registered in " + numCourses + " course(s).");
}
@Override
public String type() {
return "graduate";
}
@Override
public String toString() {
return name + " Graduate ID: " + id + " Grad Year: " + graduationYear;
}
}
The Alumni
Class
The Alumni
class represents former students. It extends Student
and includes details like admissionYear
, graduationYear
, and their current employer
. It provides overloaded constructors to handle cases where the employer information might not be immediately available.
class Alumni extends Student {
private int graduationYear;
private int admissionYear;
private String employer;
public Alumni(String name, int id, int admissionYear, int graduationYear) {
super(name, id);
this.admissionYear = admissionYear;
this.graduationYear = graduationYear;
this.employer = null; // Default to null if employer is not provided
}
public Alumni(String name, int id, int admissionYear, int graduationYear, String employer) {
super(name, id);
this.admissionYear = admissionYear;
this.graduationYear = graduationYear;
this.employer = employer;
}
@Override
public String type() {
return "alumni";
}
@Override
public String toString() {
String empStatus = (employer == null || employer.equals("Unknown")) ? "not working." : ("works at " + employer + ".");
return name + " whose ID is: " + id + " started at AUS in " + admissionYear + ".\n" +
name + " is an alumni who graduated in " + graduationYear + ".\n" +
name + " is currently " + empStatus;
}
}
The University
Class
The University
class acts as a container for a collection of Student
objects. It holds an ArrayList
of students and the university’s name, providing a centralized point for managing the student body.
class University {
private ArrayList<Student> students;
private String univName;
public University(ArrayList<Student> students, String univName) {
this.students = students;
this.univName = univName;
}
public String getUnivName() {
return univName;
}
}
System Driver and Demonstration
The Driver
class contains the main
method, which serves as the entry point for the application. It demonstrates how to instantiate various student types, add them to a University
object, and then iterate through them, showcasing polymorphism by calling methods appropriate to each student’s actual type.
public class Driver {
public static void main(String[] args) {
// Instantiate different types of students
Alumni a1 = new Alumni("Ben", 1, 1990, 1994);
Alumni a2 = new Alumni("Pamela", 2, 2000, 2004, "Microsoft");
Undergraduate s1 = new Undergraduate("Ahmed", 3, 2023);
Undergraduate s2 = new Undergraduate("Salma", 4, 2024);
Graduate s3 = new Graduate("Adam", 5, 2024, true);
Graduate s4 = new Graduate("Zain", 6, 2024, false);
// Create an ArrayList to hold all students
ArrayList<Student> students = new ArrayList<Student>();
students.add(a1);
students.add(a2);
students.add(s1);
students.add(s2);
students.add(s3);
students.add(s4);
// Create a University instance
University uni = new University(students, "AUS");
System.out.println("Welcome the " + uni.getUnivName() + " students:");
System.out.println();
// Iterate through the students, demonstrating polymorphism
for (Student s : students) {
if (s.type().equals("undergraduate")) {
Undergraduate u = (Undergraduate) s; // Downcasting
u.displayStudentLevel();
u.registerCourses();
} else if (s.type().equals("graduate")) {
Graduate g = (Graduate) s; // Downcasting
g.displayStudentLevel();
g.registerCourses();
} else { // Alumni
System.out.println(s.getName() + " is an alumni.");
}
System.out.println(s); // Calls the overridden toString() method
System.out.println();
s.save("students.txt"); // Calls the save method from the Student class
}
}
}
}
Conclusion
This Java application effectively demonstrates key OOP concepts such as inheritance and polymorphism through a practical student management scenario. By structuring the code with a clear class hierarchy, it allows for flexible and extensible management of diverse student types within a university system.