Share
Explore

Bradhurst College


Below is a complete Kotlin program that demonstrates
Inheritance,
Composition, and
passing Mutable Lists between classes,
using Unified Modeling Language (UML) concepts to model a simple college system for Bradhurst College.
This example focuses on a educational theme, modeling a student course registry system with a
Catalog object (containing courses),
a StudentRegistry object (managing students), and a
Registrar object (controller for use cases).
The program includes the requested OOP concepts and UML relationships, tailored for a straightforward, student-friendly context.

Kotlin Code: Bradhurst College Course Registry System

import kotlin.random.Random
// 1. Inheritance: Base class for all entities in the system open class Entity(val id: String) { open fun describe(): String { return "Entity ID: $id" } }
// 2. Composition and Inheritance: Course class inherits from Entity, contains no mutable lists directly class Course(val name: String, val code: String, var credits: Int) : Entity(name) { // Added 'val' to name init { require(credits > 0) { "Credits must be positive" } }
fun getDetails(): String { return "$name ($code, $credits credits)" // Now 'name' is resolved as a property }
override fun describe(): String { return "${super.describe()}, Course: ${getDetails()}" } }
// 3. Composition and Inheritance: Student class inherits from Entity, contains a mutable list of courses class Student(name: String, private var age: Int) : Entity(name) { private val enrolledCourses = mutableListOf<Course>() // Composition: Student "has-a" list of Courses
init { require(age >= 0) { "Age cannot be negative" } }
// Public method to add a course (for Registrar to use) fun enroll(course: Course) { enrolledCourses.add(course) println("${getName()} enrolled in ${course.getDetails()}") }
// Public method to get courses (for passing to Registrar or printing) fun getEnrolledCourses(): MutableList<Course> = enrolledCourses
// Getter for name (encapsulation) fun getName(): String = id
// Getter and setter for age (encapsulation) fun getAge(): Int = age fun setAge(newAge: Int) { if (newAge >= 0) age = newAge }
override fun describe(): String { return "${super.describe()}, Age: $age, Courses: ${enrolledCourses.size}" } }
// 4. Composition: Catalog class manages a mutable list of courses class Catalog { private val courses = mutableListOf<Course>()
// Add a course to the catalog fun addCourse(course: Course) { courses.add(course) println("Added ${course.getDetails()} to catalog") }
// Get courses (mutable list passed to other objects) fun getCourses(): MutableList<Course> = courses }
// 5. Composition: StudentRegistry manages a mutable list of students class StudentRegistry { private val students = mutableListOf<Student>()
// Add a student to the registry fun addStudent(student: Student) { students.add(student) println("Added ${student.getName()} to registry") }
// Get students (mutable list passed to other objects) fun getStudents(): MutableList<Student> = students
// Print schedules for all students fun printAllSchedules() { students.forEach { student -> println("\nSchedule for ${student.getName()}:") if (student.getEnrolledCourses().isEmpty()) { println("${student.getName()} has no enrolled courses.") } else { student.getEnrolledCourses().forEach { course -> println(" - ${course.getDetails()}") } } } }
// Print schedule for a specific student fun printStudentSchedule(studentName: String) { val student = students.find { it.getName() == studentName } if (student != null) { println("\nSchedule for $studentName:") if (student.getEnrolledCourses().isEmpty()) { println("$studentName has no enrolled courses.") } else { student.getEnrolledCourses().forEach { course -> println(" - ${course.getDetails()}") } } } else { println("Student $studentName not found in registry.") } } }
// 6. Composition: Registrar acts as the controller for use cases class Registrar { private val catalog = Catalog() private val registry = StudentRegistry()
// Use Case 1: Enroll a student in a course fun enrollStudent(studentName: String, courseCode: String, credits: Int = 3) { val student = registry.getStudents().find { it.getName() == studentName } val course = catalog.getCourses().find { it.code == courseCode } if (student != null && course != null) { student.enroll(course) } else { println("Error: Student $studentName or Course $courseCode not found.") } }
// Use Case 2: Print schedule for all students fun printAllSchedules() { registry.printAllSchedules() }
// Use Case 3: Print schedule for one specific student fun printStudentSchedule(studentName: String) { registry.printStudentSchedule(studentName) }
// Initialize catalog and registry with sample data fun initialize() { // Add courses to catalog catalog.addCourse(Course("Introduction to Programming", "CS101", 4)) catalog.addCourse(Course("Calculus I", "MATH101", 3)) catalog.addCourse(Course("History of Art", "ART201", 4)) catalog.addCourse(Course("Physics I", "PHY101", 3)) catalog.addCourse(Course("English Literature", "ENG101", 3)) catalog.addCourse(Course("Economics", "ECON101", 3))
// Add students to registry registry.addStudent(Student("Alice", 20)) registry.addStudent(Student("Bob", 22)) registry.addStudent(Student("Charlie", 19)) } }
// Main function to demonstrate use cases fun main() { val registrar = Registrar() registrar.initialize()
// Use Case 1: Enroll 3 students in varying ways across 6 courses registrar.enrollStudent("Alice", "CS101") // Alice enrolls in Introduction to Programming registrar.enrollStudent("Alice", "MATH101") // Alice enrolls in Calculus I registrar.enrollStudent("Bob", "ART201") // Bob enrolls in History of Art registrar.enrollStudent("Bob", "PHY101") // Bob enrolls in Physics I registrar.enrollStudent("Charlie", "ENG101") // Charlie enrolls in English Literature registrar.enrollStudent("Charlie", "ECON101") // Charlie enrolls in Economics registrar.enrollStudent("Charlie", "CS101") // Charlie enrolls in Introduction to Programming (3 courses total)
// Use Case 2: Print schedule for all students registrar.printAllSchedules()
// Use Case 3: Print schedule for one specific student registrar.printStudentSchedule("Alice") }

Output (Sample)


Added Introduction to Programming (CS101, 4 credits) to catalog
Added Calculus I (MATH101, 3 credits) to catalog

Added History of Art (ART201, 4 credits) to catalog

Added Physics I (PHY101, 3 credits) to catalog

Added English Literature (ENG101, 3 credits) to catalog

Added Economics (ECON101, 3 credits) to catalog

Added Alice to registry

Added Bob to registry

Added Charlie to registry

Alice enrolled in Introduction to Programming (CS101, 4 credits)

Alice enrolled in Calculus I (MATH101, 3 credits)

Bob enrolled in History of Art (ART201, 4 credits)

Bob enrolled in Physics I (PHY101, 3 credits)

Charlie enrolled in English Literature (ENG101, 3 credits)

Charlie enrolled in Economics (ECON101, 3 credits)

Charlie enrolled in Introduction to Programming (CS101, 4 credits)


Schedule for Alice:

- Introduction to Programming (CS101, 4 credits)

- Calculus I (MATH101, 3 credits)


Schedule for Bob:

- History of Art (ART201, 4 credits)

- Physics I (PHY101, 3 credits)


Schedule for Charlie:

- English Literature (ENG101, 3 credits)

- Economics (ECON101, 3 credits)

- Introduction to Programming (CS101, 4 credits)

Schedule for Alice:

- Introduction to Programming (CS101, 4 credits)

- Calculus I (MATH101, 3 credits)

UML Diagram Description (Conceptual)


Here’s a textual description of the UML diagram for this system, which you can sketch or generate using tools like StarUML or draw.io. This will help visualize the relationships and guide students on how to model it:
Classes (Boxes with Compartments):
Entity (Abstract Base Class):
Attributes: id: String

Operations: describe(): String (open)


Course:
Inherits from Entity (dashed arrow with triangle from Course to Entity).

Attributes: code: String, credits: Int (private, with getters implied).
Operations: getDetails(): String, describe(): String (override).


Student:
Inherits from Entity (dashed arrow with triangle from Student to Entity).
Attributes: age: Int (private, with getters/setters).
Composition: enrolledCourses: MutableList<Course> (diamond arrow from Student to Course, labeled with multiplicity 0..*).
Operations: enroll(course: Course), getEnrolledCourses(): MutableList<Course>, getName(): String, getAge(): Int, setAge(newAge: Int), describe(): String (override).


Catalog:
Attributes: courses: MutableList<Course> (private, with getter getCourses()).
Operations: addCourse(course: Course), getCourses(): MutableList<Course>.


StudentRegistry:
Attributes: students: MutableList<Student> (private, with getter getStudents()).
Operations: addStudent(student: Student), getStudents(): MutableList<Student>, printAllSchedules(), printStudentSchedule(studentName: String).


Registrar:
Composition: catalog: Catalog, registry: StudentRegistry (diamond arrows from Registrar to Catalog and StudentRegistry).
Operations: enrollStudent(studentName: String, courseCode: String, credits: Int = 3), printAllSchedules(), printStudentSchedule(studentName: String), initialize().


Relationships:
Inheritance: Course and Student inherit from Entity (generalization/specialization, dashed arrow with triangle).

Composition: Student "has-a" enrolledCourses (diamond arrow to Course), Catalog "has-a" courses (diamond to Course), StudentRegistry "has-a" students (diamond to Student), Registrar "has-a" catalog and registry (diamonds to Catalog and StudentRegistry).

Associations: Registrar interacts with Catalog and StudentRegistry via method calls (solid lines with arrows for operations like enrollStudent()).

Multiplicity:
Student to enrolledCourses: 0..* (zero or more courses per student).

Catalog to courses: 0..* (zero or more courses in catalog).

StudentRegistry to students: 0..* (zero or more students in registry).

Registrar to Catalog and StudentRegistry: 1 (exactly one instance each).

This UML diagram shows how Team A (e.g., developers designing the registrar system) can define Catalog, StudentRegistry, and Registrar with interfaces or abstract classes, while Team B (e.g., course or student developers) implements Course and Student later, passing mutable lists to ensure flexibility and collaboration.

Explanation of UML and Team Collaboration

Inheritance in UML: Entity as a base class ensures shared identity (id) across Course and Student, modeled with generalization. Team A can define Entity and expect Team B to extend it for specific entities, ensuring consistency.

Composition in UML: Diamond arrows show ownership (e.g., Student owns enrolledCourses), enabling Team A to design StudentRegistry and Catalog to manage lists, while Team B implements Course and Student to populate them.

Mutable Lists and Passing:
UML associations with multiplicity (e.g., 0..*) model mutable lists passed between Catalog, StudentRegistry, and Registrar.
Team A can write Registrar to operate on getCourses() and getStudents(), assuming Team B provides compliant implementations.

Team A and B Collaboration:
Team A designs Registrar to call Catalog.getCourses() and StudentRegistry.getStudents(), using UML to specify interfaces or abstract methods.
Even if Team B hasn’t implemented Course or Student, Team A can mock these classes or use interfaces (e.g., Bookable from Lab 10), ensuring parallel development for Bradhurst College’s system.

Talking Points for Lab Preview

Inheritance, composition, and mutable lists model Bradhurst College’s course system—Student inherits from Entity, composes courses, and passes lists to Registrar for use cases like enrolling in programming or art
UML diagrams let Team A design Registrar and Catalog before Team B implements Course and Student, ensuring modular, scalable systems for Bradhurst College.
This ties to Labs 5–10: inheritance (Lab 5), composition (Lab 9), interfaces (Lab 10), and encapsulation (Lab 8) for passing lists safely.

Instructor Notes

Tools: IntelliJ for code, projector for sharing, whiteboard or UML tool (e.g., StarUML) for diagrams.

Tie to Curriculum: Reference Labs 5–10, focusing on a relatable college theme (e.g., Bradhurst courses, students), and null safety (optional extension for mutable lists).

Next Steps: Transition to full labs on inheritance, composition, interfaces, and mutable lists, building on this preview.

This code and UML description provide a clear, practical introduction to modeling a simple college system with Kotlin and UML, aligning with your educational theme and curriculum.
Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.