DEPARTMENT OF COMPUTER SCIENCE · OBJECT-ORIENTED PROGRAMMING
CTR214
Object-Oriented Programming
Complete Course Notes — Java Edition
From Fundamentals to GUI Application Development
10 OOP GUI Full Projects
Units Pillars Dev Code Incl.
About This Document
These notes teach Java OOP from first principles through to complete GUI applications.
Every concept is explained clearly, illustrated with diagrams, and demonstrated with
working code examples. Suitable for students with basic programming knowledge and prior
Java experience.
Prepared by: Mr. Ngassa
Academic Year 2025/2026
Department of Computer Science · Java 17+ LTS Edition
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
TABLE OF CONTENTS
Course Introduction & Java Overview .............................................. 3
1 Classes, Objects & Encapsulation .............................................. 5
1.1 What is a Class? ............................................ 5
1.2 Objects & Instances ............................................ 6
1.3 Encapsulation & Access Modifiers ............................................ 7
1.4 Instance vs Class Variables & Methods ............................................ 8
2 Constructors, JVM & Memory Management .............................................. 10
2.1 Constructors & Default Mechanisms ............................................ 10
2.2 The JVM & Compiled Bytecode ............................................ 11
2.3 Garbage Collection ............................................ 12
3 Inheritance, Polymorphism & Casting .............................................. 14
3.1 Inheritance ............................................ 14
3.2 Method Overriding & Polymorphism ............................................ 15
3.3 Abstract Classes ............................................ 16
3.4 Interfaces ............................................ 17
3.5 Casting ............................................ 18
4 Exceptions, Packages & Access Modifiers .............................................. 20
4.1 Exception Handling ............................................ 20
4.2 Custom Exceptions ............................................ 22
4.3 Packages ............................................ 23
4.4 Full Access Modifier Table ............................................ 24
5 Strings, Collections & Utility Classes .............................................. 25
5.1 String & StringBuffer ............................................ 25
5.2 Wrapper Classes ............................................ 27
5.3 ArrayList, LinkedList, Vector ............................................ 28
5.4 HashMap & Collections Framework ............................................ 30
6 I/O Streams, Files & Serialization .............................................. 32
6.1 File I/O Streams ............................................ 32
6.2 Object Serialization ............................................ 34
7 Copying, Cloning & Object Duplication .............................................. 36
8 Control Structures & Statements .............................................. 38
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 2
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
8.1 Conditional Statements ............................................ 38
8.2 Loops & Iterations ............................................ 39
9 GUI Programming with Swing & JavaFX .............................................. 41
9.1 Event-Driven Programming ............................................ 41
9.2 Swing Components ............................................ 42
9.3 Event Handling ............................................ 44
9.4 JavaFX Introduction ............................................ 46
10 Application Design & Mini-Project .............................................. 48
10.1 Two-Layer Architecture ............................................ 48
10.2 Mini-Project: Student Grade System ............................................ 50
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 3
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
COURSE INTRODUCTION
Why Java? Why Object-Oriented Programming?
What is Object-Oriented Programming?
Object-Oriented Programming (OOP) is a programming paradigm that organises software design
around data, or objects, rather than functions and logic. An object is anything that has a state (data)
and behaviour (methods). Real-world entities — a bank account, a car, a student — map naturally
to objects in code.
Before OOP, programs were written as long sequences of instructions (procedural programming).
As programs grew larger, this became unmanageable. OOP solves this by breaking complex systems
into small, self-contained objects that communicate with each other.
Figure: The Four Pillars of OOP — Encapsulation, Inheritance, Polymorphism, Abstraction
Encapsulation Inheritance
Bundling data and the methods that operate A mechanism by which one class (child)
on that data within a single unit (class), and acquires properties and behaviours of another
restricting direct access to some of the object's class (parent), promoting code reuse.
components.
Polymorphism Abstraction
The ability of different classes to be treated as Hiding complex implementation details and
instances of the same class through a common exposing only the essential features of an
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 4
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
interface. One interface, many object. Achieved via abstract classes and
implementations. interfaces.
Why Java?
Java Advantage Explanation
Platform Independence Java compiles to bytecode that runs on any JVM — Write
Once, Run Anywhere (WORA).
Strongly Typed Type checking at compile time catches errors early, before
your program runs.
Garbage Collection Java automatically manages memory — no manual malloc/free
like in C++.
Vast Ecosystem Millions of libraries, frameworks (Spring, Android SDK), and
tools available.
Industry Dominant Used in Android development, enterprise back-ends, banking
systems, Big Data.
Pure OOP Everything in Java (except primitives) is an object — enforces
OOP discipline.
Setting Up Your Environment
To write and run Java programs you need two things:
1. JDK (Java Development Kit) — Download from [Link] — choose Java 17 LTS.
This includes the Java compiler (javac) and runtime (java).
2. IDE (Integrated Development Environment) — Use IntelliJ IDEA Community Edition (free)
from [Link]/idea. VS Code with the Extension Pack for Java also works well.
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 5
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
JAVA
// Your first Java program — type this exactly as shown
// File name MUST match the class name: [Link]
public class HelloWorld {
public static void main(String[] args) {
[Link]("Hello, World!"); // print to console
[Link]("Welcome to CTR214 — OOP in Java!");
}
}
// To compile: open terminal in the same folder and type:
// javac [Link]
// To run:
// java HelloWorld
// Expected output:
// Hello, World!
// Welcome to CTR214 — OOP in Java!
KEY RULE
In Java, the file name must EXACTLY match the class name (including capitalisation), and it
must end in .java. [Link] contains class HelloWorld. This is not optional — the
compiler will refuse to compile if names do not match.
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 6
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
UNIT 1
Classes, Objects & Encapsulation
The building blocks of every Java program
1.1 What is a Class?
A class is a blueprint or template for creating objects. It defines the
structure (fields/variables) and behaviour (methods) that every object
Class
created from it will have. Think of a class as a cookie cutter and
objects as the cookies.
Real-world analogy: The blueprint for a house is the class. An actual house built from that blueprint
is an object. Many houses (objects) can be built from the same blueprint (class), each with different
values for their fields (colour, number of rooms).
Figure: Anatomy of a Java Class — Fields, Constructor, Methods
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 7
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
Class Syntax
A Java class has the following structure:
JAVA
// A complete, well-structured Java class
// File: [Link]
public class BankAccount {
// ── FIELDS (instance variables) ──────────────────────────────
// These store the STATE of each object
private String accountHolder; // who owns the account
private double balance; // current balance
private String accountNumber; // unique ID
// ── CONSTRUCTOR ──────────────────────────────────────────────
// Called when we create a new BankAccount object
public BankAccount(String holder, String number, double
initialBalance) {
[Link] = holder;
[Link] = number;
[Link] = initialBalance;
}
// ── METHODS (instance methods) ───────────────────────────────
// These define the BEHAVIOUR of each object
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
[Link]("Deposited: GHS " + amount);
}
}
public void withdraw(double amount) {
if (amount > 0 && amount <= balance) {
balance -= amount;
[Link]("Withdrawn: GHS " + amount);
} else {
[Link]("Insufficient funds!");
}
}
public double getBalance() {
return balance; // returns the current balance
}
public void printStatement() {
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 8
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
[Link]("Account: " + accountNumber);
[Link]("Holder: " + accountHolder);
[Link]("Balance: GHS " + balance);
}
}
1.2 Objects and Instances
An object is a specific instance of a class created in memory. When you write new BankAccount(...),
Java allocates memory for a new object and returns a reference to it. The variable (e.g., account1)
holds this reference — it is not the object itself, but a pointer to where the object lives in memory.
JAVA
// File: [Link]
// Creating and using objects
public class Main {
public static void main(String[] args) {
// Create TWO separate BankAccount objects
// Each has its own copy of the fields
BankAccount account1 = new BankAccount("Kofi Mensah",
"ACC001", 500.0);
BankAccount account2 = new BankAccount("Ama Asante",
"ACC002", 1200.0);
// Calling methods on account1 (does NOT affect account2)
[Link](200.0); // ACC001 balance is now 700.0
[Link](100.0); // ACC001 balance is now 600.0
// Calling methods on account2 independently
[Link](300.0); // ACC002 balance is now 1500.0
// Print statements for both
[Link]();
[Link]("---");
[Link]();
// Output for account1:
// Deposited: GHS 200.0
// Withdrawn: GHS 100.0
// Account: ACC001
// Holder: Kofi Mensah
// Balance: GHS 600.0
}
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 9
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
IMPORTANT CONCEPT
Every object has its own independent copy of instance variables (fields). Changing
[Link] does NOT change [Link]. This is the essence of object
independence in OOP.
1.3 Encapsulation and Access Modifiers
The principle of hiding an object's internal state and requiring all
interaction to occur through well-defined methods. This protects data
Encapsulation from accidental corruption and allows the internal implementation to
change without breaking external code. This is often called “data
hiding”.
Analogy: Think of a vending machine. You interact with it through a public interface (buttons, coin
slot, display). You cannot directly access the internal mechanisms (the money box, the motors, the
product coils). This protects the internal machinery from misuse and ensures that all interactions
happen through a controlled process.
How it works in Java:
• Use private access modifiers for instance variables.
• Provide public getter and setter methods to allow controlled access to those variables. This
allows you to add validation logic (e.g., preventing a negative age).
In Java, encapsulation is implemented through access modifiers on fields and methods. The
standard pattern is: make all fields private, then provide public getter and setter methods to read
and write them.
Access Modifier Who Can Access This Member?
public Everyone — any class in any package
private Only the class itself — not even subclasses
protected The class itself, subclasses, and classes in the same package
(no modifier) Classes in the same package only (package-private)
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 10
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
JAVA
// BEFORE encapsulation (BAD — fields are public, anyone can corrupt
data)
class StudentBad {
public int age; // DANGEROUS: anyone can set age = -500
public String name;
}
// Someone could write:
// StudentBad s = new StudentBad();
// [Link] = -500; // No validation! Data is corrupt!
// ════════════════════════════════════════════════════════════════
// AFTER encapsulation (GOOD — fields are private, access via
methods)
public class Student {
private int age; // Cannot be accessed directly from
outside
private String name;
private double gpa;
// GETTER — read the value
public int getAge() {
return age;
}
// SETTER — write the value WITH validation
public void setAge(int age) {
if (age >= 16 && age <= 60) { // only valid ages allowed
[Link] = age;
} else {
[Link]("Error: Invalid age " + age);
}
}
public String getName() { return name; }
public void setName(String name) {
if (name != null && ![Link]()) {
[Link] = name;
}
}
public double getGpa() { return gpa; }
public void setGpa(double gpa) {
if (gpa >= 0.0 && gpa <= 4.0) { [Link] = gpa; }
}
}
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 11
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
// Now invalid data is IMPOSSIBLE:
// Student s = new Student();
// [Link](-500); // prints: Error: Invalid age -500 (data
protected!)
Example 2 :
JAVA
public class BankAccount {
// Private data - hidden from outside world
private String accountNumber;
private double balance;
// Public constructor
public BankAccount(String accountNumber, double initialBalance)
{
[Link] = accountNumber;
[Link] = initialBalance;
}
// Public getter - controlled read access
public double getBalance() {
return balance;
}
// Public methods - controlled way to modify data
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
[Link]("Deposited: $" + amount);
}
}
public void withdraw(double amount) {
if (amount > 0 && amount <= balance) {
balance -= amount;
[Link]("Withdrew: $" + amount);
} else {
[Link]("Insufficient funds or invalid
amount.");
}
}
// Note: No setter for balance to prevent arbitrary changes.
// Balance can only be changed through deposit/withdraw methods.
}
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 12
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
1.4 Instance vs Class Variables and Methods
Java has two types of variables and methods within a class: instance members (belong to each
individual object) and class members (shared across ALL objects, declared with the static keyword).
JAVA
public class Counter {
// ── CLASS VARIABLE (static) ──────────────────────────────────
// Shared by ALL Counter objects — there is only ONE copy of
this
private static int totalCounters = 0;
// ── INSTANCE VARIABLE ───────────────────────────────────────
// Each Counter object has its OWN copy of this
private int count;
private String name;
public Counter(String name) {
[Link] = name;
[Link] = 0;
totalCounters++; // increment the SHARED counter
}
// INSTANCE METHOD — operates on THIS specific object
public void increment() { count++; }
public int getCount() { return count; }
// CLASS METHOD (static) — does NOT operate on any specific
object
// Called as: [Link]() (NOT
[Link]())
public static int getTotalCounters() { return totalCounters; }
}
// Demonstration:
// Counter c1 = new Counter("Page Views");
// Counter c2 = new Counter("Button Clicks");
// Counter c3 = new Counter("Login Attempts");
//
// [Link](); [Link](); // [Link] = 2
// [Link](); // [Link] = 1
//
// [Link]([Link]()); // 2 (instance)
// [Link]([Link]()); // 1 (instance)
// [Link]([Link]()); // 3
(class/static)
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 13
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
Instance Member Class (Static) Member
Belongs to each individual object Belongs to the class itself — shared by all objects
Each object has its own copy of Only ONE copy exists regardless of how many objects are
the variable created
Accessed via object reference: Accessed via class name: [Link]
[Link]
Cannot be called without an Can be called without creating any object at all
object
Example: [Link] Example: [Link], [Link]()
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 14
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
UNIT 2
Constructors, JVM & Memory Management
How objects are created, how Java runs, and how memory is managed
2.1 Constructors and Default Mechanisms
A special method that is called automatically when an object is
Constructor created using the new keyword. It has the same name as the class, no
return type, and is used to initialise the object's fields.
JAVA
public class Rectangle {
private double width;
private double height;
private String colour;
// ── DEFAULT CONSTRUCTOR (no parameters) ──────────────────────
// Java provides this AUTOMATICALLY if you write no constructor
at all.
// If you define ANY constructor, Java removes the automatic
default.
public Rectangle() {
[Link] = 1.0; // sensible default values
[Link] = 1.0;
[Link] = "white";
}
// ── PARAMETERISED CONSTRUCTOR
─────────────────────────────────
public Rectangle(double width, double height) {
[Link] = width;
[Link] = height;
[Link] = "white";
}
// ── FULL CONSTRUCTOR
──────────────────────────────────────────
public Rectangle(double width, double height, String colour) {
[Link] = width;
[Link] = height;
[Link] = colour;
}
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 15
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
// ── CONSTRUCTOR CHAINING using this() ────────────────────────
// Calls another constructor in the same class — avoids code
duplication
// Must be the FIRST statement if used
public Rectangle(double side) {
this(side, side, "blue"); // creates a blue square
}
public double getArea() { return width * height; }
public double getPerimeter() { return 2 * (width + height); }
}
// Usage:
// Rectangle r1 = new Rectangle(); // default: 1x1 white
// Rectangle r2 = new Rectangle(5.0, 3.0); // 5x3 white
// Rectangle r3 = new Rectangle(4.0, 2.0, "red"); // 4x2 red
// Rectangle r4 = new Rectangle(6.0); // 6x6 blue square
// [Link]([Link]()); // 15.0
THE THIS KEYWORD
Inside any instance method or constructor, the keyword this refers to the current object. It
is used when a parameter name shadows a field name ([Link] = width), or to call
another constructor from within a constructor (this(...)).
2.2 The JVM and Compiled Bytecode
Understanding how Java works behind the scenes is essential for writing efficient code and
diagnosing problems. The Java execution model has two stages: compilation and execution.
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 16
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
Figure: Java Execution Pipeline — Source Code → Bytecode → JVM → Output
Stage What Happens
1. Write Source Code You write .java files using any text editor or IDE
2. Compile (javac) The Java compiler translates .java files into platform-neutral .class
bytecode files
3. JVM Loads .class The Java Virtual Machine (JVM) reads the bytecode — the same .class
file runs on Windows, Mac, Linux
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 17
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
4. Class Loader JVM's class loader loads .class files into memory when they are first
needed
5. JIT Compilation Just-In-Time compiler converts frequently executed bytecode to native
machine code for speed
6. Execution The JVM executes the program, managing memory, threads, and
security
This architecture is why Java is called 'Write Once, Run Anywhere'. The bytecode (.class) is identical
whether it was compiled on Windows or Ubuntu. The JVM installed on each platform translates it
to native instructions appropriate for that machine.
JAVA
// You write this ([Link]):
public class HelloWorld {
public static void main(String[] args) {
[Link]("Hello");
}
}
// javac [Link] → produces [Link] (bytecode)
// This .class file is identical on all platforms.
// java HelloWorld → JVM reads [Link], runs it
// Same command on Windows, Mac, Linux — same result.
2.3 Garbage Collection
An automatic memory management system built into the JVM that
Garbage Collector identifies objects that are no longer reachable from any live part of
the program, and reclaims their memory automatically.
In C++, programmers must manually delete objects using the delete keyword. Forgetting to do so
causes memory leaks. Java eliminates this entire class of bugs by automatically freeing unreachable
objects.
JAVA
public class GarbageDemo {
public static void main(String[] args) {
// Object 1: account1 points to a BankAccount object
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 18
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
BankAccount account1 = new BankAccount("Kofi", "ACC001",
500.0);
// Object 2: account2 points to a different BankAccount
BankAccount account2 = new BankAccount("Ama", "ACC002",
1000.0);
// account1 now points to account2's object
// The ORIGINAL account1 object (ACC001) is now unreachable
— ELIGIBLE FOR GC
account1 = account2;
// Setting to null explicitly makes the object eligible for
GC immediately
account2 = null;
// You CANNOT force GC, but you can suggest it:
[Link](); // JVM will run GC 'at some point soon' — not
guaranteed immediately
// Note: You should never rely on finalize() for resource
cleanup.
// Use try-with-resources for files, connections, etc.
}
}
// Key points:
// 1. GC runs automatically — you don't free memory manually
// 2. An object becomes eligible for GC when no references point to
it
// 3. GC runs in a background thread — timing is not guaranteed
// 4. For resources like files/DB connections, use try-with-
resources
Java GC (Automatic) C++ Manual Memory (for comparison)
Objects freed automatically Developer must call delete ptr; explicitly
when unreachable
No memory leaks from forgotten Memory leaks if delete is forgotten
frees
No use-after-free bugs Accessing freed memory causes undefined behaviour
GC pauses program briefly to run No pauses — but much more error-prone
Suitable for most applications Used where real-time control over memory is required
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 19
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
UNIT 3
Inheritance, Polymorphism & Interfaces
Reusing code and building flexible hierarchies
3.1 Inheritance
A mechanism where a new class (child/subclass) inherits fields and
methods from an existing class (parent/superclass). The child
Inheritance
automatically gets all public and protected members of the parent,
and can add new ones or override existing ones.
Real-world analogy: All animals breathe and eat — these are inherited from the Animal parent
class. But a Dog also barks, and a Cat meows — these are behaviours unique to each subclass.
How it works in Java:
• Use the ‘extends’ keyword.
• The subclass inherits all public and protected members of the superclass.
• The subclass can override methods to provide specific implementations.
Figure: Java Inheritance Hierarchy — Animal → Dog / Cat → GoldenRetriever
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 20
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
JAVA
// ── PARENT CLASS (Superclass)
─────────────────────────────────────
public class Animal {
protected String name;
protected int age;
public Animal(String name, int age) {
[Link] = name;
[Link] = age;
}
public void breathe() {
[Link](name + " is breathing.");
}
public void eat(String food) {
[Link](name + " eats " + food);
}
public void sleep() {
[Link](name + " is sleeping.");
}
public void describe() {
[Link]("I am " + name + ", age " + age);
}
}
// ── CHILD CLASS (Subclass)
────────────────────────────────────────
// 'extends' keyword establishes the inheritance relationship
public class Dog extends Animal {
private String breed; // NEW field only Dog has
// Child constructor MUST call parent constructor using super()
public Dog(String name, int age, String breed) {
super(name, age); // MUST be first line — calls
Animal(name, age)
[Link] = breed;
}
// NEW method — only Dog has this
public void bark() {
[Link](name + " says: Woof! Woof!");
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 21
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
// OVERRIDE parent method — Dog's version of describe()
@Override
public void describe() {
[Link](); // call parent's version first
[Link]("Breed: " + breed);
}
}
// ── ANOTHER CHILD CLASS
───────────────────────────────────────────
public class Cat extends Animal {
private boolean isIndoor;
public Cat(String name, int age, boolean isIndoor) {
super(name, age);
[Link] = isIndoor;
}
public void meow() {
[Link](name + " says: Meow!");
}
@Override
public void describe() {
[Link]();
[Link](isIndoor ? "Indoor cat" : "Outdoor cat");
}
}
// ── USING INHERITANCE
─────────────────────────────────────────────
// Dog d = new Dog("Rex", 3, "German Shepherd");
// [Link](); // inherited from Animal
// [Link]("bones"); // inherited from Animal
// [Link](); // Dog's own method
// [Link](); // Dog's OVERRIDDEN version
//
// Output:
// Rex is breathing.
// Rex eats bones
// Woof! Woof!
// I am Rex, age 3
// Breed: German Shepherd
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 22
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
THE SUPER KEYWORD
super refers to the parent class. Use super() in a constructor to call the parent constructor
(must be first line). Use [Link]() inside a method to call the parent class
version of an overridden method.
3.2 Polymorphism
The ability for a parent class reference to hold objects of different
Polymorphism child classes, and to call overridden methods that execute the correct
version at runtime. Poly = many, Morph = forms.
Figure: Polymorphism — One Reference Type, Many Implementations
Polymorphism is a core concept in object-oriented programming (OOP) where a single reference
type (like a parent class or interface) can be used to refer to objects of many different
implementation types.
Key Characteristics
• One Interface, Multiple Behaviors: A single method name can perform different actions
depending on the actual object it is called on at runtime.
• Decoupling: It allows you to write code that interacts with a general type (e.g., Shape)
without needing to know the specific details of its children (e.g., Circle, Square).
• Dynamic Binding: The specific implementation to execute is determined at runtime by the
virtual machine based on the object's actual class.
Common Examples
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 23
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
• Animal System: A reference of type Animal can point to a Dog or a Cat. When
calling .makeNoise(), the Dog barks and the Cat meows.
• Payment Systems: A Payment interface can have implementations for CreditCard, PayPal,
or Bitcoin. The system calls .process() regardless of the specific method used.
JAVA
// Polymorphism in action — the POWER of OOP
public class PolymorphismDemo {
public static void main(String[] args) {
// An Animal reference can hold ANY subclass object
Animal a1 = new Dog("Rex", 3, "Husky");
Animal a2 = new Cat("Luna", 2, true);
Animal a3 = new Animal("Generic", 5);
// Create an array of Animals — mix of Dog and Cat objects
Animal[] zoo = { a1, a2, a3 };
// Polymorphic loop — calls the CORRECT describe() for each
type
// This is decided at RUNTIME (dynamic dispatch)
for (Animal animal : zoo) {
[Link](); // calls [Link]() for Rex,
[Link]() for Luna
[Link]();
[Link]("---");
}
// Runtime type checking with instanceof
for (Animal animal : zoo) {
if (animal instanceof Dog) {
Dog d = (Dog) animal; // safe cast — we checked
first
[Link]();
} else if (animal instanceof Cat) {
Cat c = (Cat) animal;
[Link]();
}
}
}
// Method that works with ANY Animal subclass — true
polymorphism
public static void makeAnimalEat(Animal a) {
[Link]("food"); // works for Dog, Cat, or any future
subclass
}
}
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 24
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
3.3 Abstract Classes
A class that cannot be instantiated directly — you cannot create an
object of an abstract class. It can contain abstract methods (no body,
Abstract Class
must be implemented by subclasses) and concrete methods (with a
full body, inherited by subclasses).
JAVA
// Abstract class — defines a TEMPLATE for subclasses
// Cannot do: Shape s = new Shape(); — compiler error!
public abstract class Shape {
protected String colour;
public Shape(String colour) {
[Link] = colour;
}
// ABSTRACT METHODS — no body, MUST be implemented by every
subclass
public abstract double getArea();
public abstract double getPerimeter();
public abstract String getShapeName();
// CONCRETE METHOD — has a body, inherited by all subclasses
public void printInfo() {
[Link](getShapeName() + " (" + colour + ")");
[Link](" Area: " + getArea());
[Link](" Perimeter: " + getPerimeter());
}
}
// ── Concrete subclass 1 ──────────────────────────────────────────
public class Circle extends Shape {
private double radius;
public Circle(String colour, double radius) {
super(colour);
[Link] = radius;
}
@Override public double getArea() { return [Link] * radius
* radius; }
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 25
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
@Override public double getPerimeter() { return 2 * [Link] *
radius; }
@Override public String getShapeName() { return "Circle"; }
}
// ── Concrete subclass 2 ──────────────────────────────────────────
public class Triangle extends Shape {
private double a, b, c; // three sides
public Triangle(String colour, double a, double b, double c) {
super(colour);
this.a = a; this.b = b; this.c = c;
}
@Override public double getArea() {
double s = (a+b+c)/2;
return [Link](s*(s-a)*(s-b)*(s-c)); // Heron's formula
}
@Override public double getPerimeter() { return a + b + c; }
@Override public String getShapeName() { return "Triangle"; }
}
// Usage:
// Shape[] shapes = { new Circle("red", 5), new
Triangle("blue",3,4,5) };
// for (Shape s : shapes) [Link](); // polymorphic call
3.4 Interfaces
A completely abstract type that defines a contract — a set of method
signatures that any implementing class MUST provide. An interface
Interface
has no instance variables and (traditionally) no method bodies. A
class can implement multiple interfaces.
Interfaces solve a key limitation of Java: a class can only extend ONE parent class (Java does not
support multiple inheritance of classes). But a class can implement as many interfaces as needed.
JAVA
// ── INTERFACES — defining contracts
───────────────────────────────
// Any class that implements Printable MUST provide a print() method
public interface Printable {
void print(); // automatically public and abstract
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 26
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
// Any class implementing Saveable must provide save() and load()
public interface Saveable {
boolean save(String filename);
boolean load(String filename);
}
// ── A class can implement MULTIPLE interfaces
─────────────────────
public class Document implements Printable, Saveable {
private String content;
private String title;
public Document(String title, String content) {
[Link] = title;
[Link] = content;
}
// Must implement ALL methods from Printable
@Override
public void print() {
[Link]("=== " + title + " ===");
[Link](content);
}
// Must implement ALL methods from Saveable
@Override
public boolean save(String filename) {
[Link]("Saving '" + title + "' to " + filename);
// real implementation would write to disk
return true;
}
@Override
public boolean load(String filename) {
[Link]("Loading from " + filename);
return true;
}
}
// Interfaces enable polymorphism across unrelated class
hierarchies:
// Printable p = new Document("Report", "Content here...");
// [Link](); // works because Document implements Printable
Abstract Class Interface
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 27
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
Can have concrete methods with Traditionally all methods are abstract (no bodies)
bodies (since Java 8 interfaces
can too via default)
Can have instance variables Cannot have instance variables (only constants)
A class can extend only ONE A class can implement MULTIPLE interfaces
abstract class
Use when subclasses SHARE Use to define a CONTRACT multiple unrelated classes must
common code follow
Example: Shape with getArea() Example: Comparable, Serializable, Runnable
abstract
3.5 Casting
Casting is converting a reference from one type to another within an inheritance hierarchy. There
are two kinds: upcasting (child → parent, always safe) and downcasting (parent → child, may fail at
runtime).
JAVA
// ── UPCASTING (implicit, always safe) ────────────────────────────
// A Dog IS-A Animal, so this is always valid
Dog d = new Dog("Rex", 3, "Husky");
Animal a = d; // UPCASTING — no cast syntax needed, automatic
// Now 'a' can only call Animal methods (not bark())
[Link](); // OK — Animal method
// [Link](); // COMPILE ERROR — Animal reference doesn't know
bark()
// ── DOWNCASTING (explicit, may fail at runtime) ──────────────────
// ALWAYS check with instanceof BEFORE downcasting
Animal animal = new Dog("Rex", 3, "Husky"); // upcast stored
if (animal instanceof Dog) { // check first — SAFE
Dog dog = (Dog) animal; // explicit downcast
[Link](); // now we can call Dog methods
}
// ── DANGEROUS DOWNCAST (ClassCastException) ──────────────────────
Animal cat = new Cat("Luna", 2, true);
// Dog badDog = (Dog) cat; // RUNTIME ERROR: Cat cannot be cast to
Dog
// // ClassCastException!
// Modern Java (16+): Pattern Matching for instanceof
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 28
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
if (animal instanceof Dog dog) { // combines check AND cast
[Link](); // 'dog' is already the Dog reference
}
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 29
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
UNIT 4
Exceptions, Packages & Access Modifiers
Writing robust, well-organised Java programs
4.1 Exception Handling
An event that disrupts the normal flow of a program during
execution. In Java, exceptions are objects that represent errors or
Exception
unexpected conditions. They can be caught and handled gracefully
rather than crashing the program.
Without exception handling, a single bad input can crash your entire program. With it, you can
catch the error, display a meaningful message, and continue running — or shut down gracefully.
Figure: Exception Flow — Normal Path vs Exception Path (try-catch-finally)
The flow of a try-catch-finally block defines how a program handles potential runtime errors,
distinguishing between a successful execution and one that encounters an issue.
1. Normal Path (No Exception)
• Try Block: The program enters the try block and executes all statements sequentially.
• Catch Block: Since no error occurs, the catch block is entirely skipped.
• Finally Block: The program proceeds directly to the finally block, which executes regardless
of the outcome.
• Post-Block: Execution continues with any code following the finally block.
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 30
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
2. Exception Path (Error Occurs)
• Try Block: Execution starts in the try block but stops immediately at the line where the
exception is thrown.
• Catch Block: The JVM (or relevant engine) looks for a matching catch block. If found, the
code inside that block runs to handle the error (e.g., logging or recovery).
• Finally Block: After the catch block finishes, the finally block is executed.
• Post-Block: If the exception was handled, the program continues; if not, it may terminate or
propagate the error further.
JAVA
// ── BASIC TRY-CATCH ──────────────────────────────────────────────
public class ExceptionDemo {
public static void main(String[] args) {
// Example 1: ArithmeticException (division by zero)
try {
int result = 10 / 0; // throws ArithmeticException
[Link](result); // never reached
} catch (ArithmeticException e) {
[Link]("Math error: " + [Link]()); //
/ by zero
}
// Example 2: NumberFormatException
try {
String input = "abc";
int num = [Link](input); // throws
NumberFormatException
} catch (NumberFormatException e) {
[Link]("Cannot convert '" + "abc" + "' to a
number");
}
// Example 3: Multiple catch blocks
String[] names = {"Alice", "Bob"};
try {
[Link](names[5]); //
ArrayIndexOutOfBoundsException
[Link]([Link]()); //
NullPointerException
} catch (ArrayIndexOutOfBoundsException e) {
[Link]("Index out of range: " +
[Link]());
} catch (NullPointerException e) {
[Link]("Null reference encountered");
} catch (Exception e) {
// Catch-all — catches any other Exception not caught
above
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 31
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
[Link]("Unexpected error: " +
[Link]());
} finally {
// ALWAYS executes — whether exception occurred or not
// Use for cleanup: closing files, releasing resources
[Link]("This always runs (finally block)");
}
}
}
Exception Type When It Occurs
ArithmeticException Division by zero: int x = 5 / 0
NullPointerException Calling a method on a null reference: String s = null;
[Link]()
ArrayIndexOutOfBoundsException Accessing an invalid array index: arr[10] when arr has 5
elements
NumberFormatException Parsing non-numeric string: [Link]("abc")
ClassCastException Invalid downcast: (Dog) catObject
FileNotFoundException Opening a file that does not exist
IOException General I/O failure reading or writing files/streams
IllegalArgumentException Method receives invalid argument
JAVA
// ── TRY-WITH-RESOURCES (Java 7+) ────────────────────────────────
// Automatically closes the resource when done — even if exception
occurs
// This replaces the old try { ... } finally { [Link](); }
pattern
import [Link].*;
try (BufferedReader reader = new BufferedReader(new
FileReader("[Link]"))) {
String line;
while ((line = [Link]()) != null) {
[Link](line);
}
// [Link]() is called AUTOMATICALLY here
} catch (FileNotFoundException e) {
[Link]("File not found: [Link]");
} catch (IOException e) {
[Link]("Error reading file: " + [Link]());
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 32
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
4.2 Custom Exceptions
You can create your own exception classes to represent domain-specific errors in your application.
This makes error handling more meaningful and self-documenting.
JAVA
// ── DEFINING A CUSTOM EXCEPTION ──────────────────────────────────
// Extend RuntimeException for unchecked, or Exception for checked
exceptions
public class InsufficientFundsException extends Exception {
private double amount; // how much was requested
private double balance; // what was available
public InsufficientFundsException(double amount, double balance)
{
super([Link]("Withdrawal of GHS %.2f failed. Balance:
GHS %.2f",
amount, balance));
[Link] = amount;
[Link] = balance;
}
public double getShortfall() { return amount - balance; }
}
// ── USING THE CUSTOM EXCEPTION ───────────────────────────────────
public class SafeBankAccount {
private double balance;
public SafeBankAccount(double balance) { [Link] = balance;
}
// 'throws' declares that this method can throw this exception
public void withdraw(double amount) throws
InsufficientFundsException {
if (amount > balance) {
throw new InsufficientFundsException(amount, balance);
}
balance -= amount;
}
}
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 33
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
// Main usage:
// SafeBankAccount acc = new SafeBankAccount(100.0);
// try {
// [Link](500.0);
// } catch (InsufficientFundsException e) {
// [Link]([Link]());
// [Link]("You need GHS " + [Link]() + "
more");
// }
4.3 Packages
A namespace that organises related classes and interfaces into
Package groups. Packages prevent naming conflicts (two classes named User
in different packages are distinct) and control access between classes.
JAVA
// ── DECLARING A PACKAGE ──────────────────────────────────────────
// First line of EVERY source file (except files in default package)
package [Link]; // corresponds to directory
path
public class BankAccount {
// ... class body
}
// ── IMPORTING FROM ANOTHER PACKAGE ───────────────────────────────
package [Link];
import [Link]; // import
specific class
import [Link].*; // import all of
[Link]
public class BankingApp {
public static void main(String[] args) {
BankAccount acc = new BankAccount("Kofi", "001", 500);
}
}
// ── STANDARD JAVA PACKAGES TO KNOW ───────────────────────────────
// [Link] — automatically imported: String, Math, Integer,
System
// [Link] — ArrayList, HashMap, Scanner, Date, Arrays
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 34
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
// [Link] — File, InputStream, OutputStream, BufferedReader
// [Link] — modern file I/O (NIO.2)
// [Link] — Socket, URL, HttpURLConnection
// [Link] — JFrame, JButton, JTextField — GUI components
// javafx.* — modern JavaFX GUI framework
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 35
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
UNIT 5
Strings, Collections & Utility Classes
Java's most-used built-in classes
5.1 String and StringBuffer
An immutable sequence of characters in Java. Once created, a String
String object cannot be changed. Any operation that appears to modify a
String actually creates a NEW String object.
Strings are one of the most frequently used classes in Java. Understanding their immutability is
critical for writing efficient code.
JAVA
// ── STRING BASICS ────────────────────────────────────────────────
String name = "Kofi Mensah";
String greeting = "Hello, " + name + "!"; // creates new String
object
// ── COMMON STRING METHODS
─────────────────────────────────────────
String s = "Object-Oriented Programming";
[Link]([Link]()); // 28
[Link]([Link]()); // OBJECT-ORIENTED
PROGRAMMING
[Link]([Link]()); // object-oriented
programming
[Link]([Link](0)); // O
[Link]([Link]("Oriented")); // 7 (starting index)
[Link]([Link]("Program")); // true
[Link]([Link](7, 15)); // Oriented
[Link]([Link]("-", " ")); // Object Oriented
Programming
[Link]([Link]("Object")); // true
[Link]([Link]()); // removes
leading/trailing spaces
[Link]([Link]("-")[0]); // Object
// ── STRING COMPARISON — CRITICAL GOTCHA ──────────────────────────
String a = "hello";
String b = "hello";
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 36
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
String c = new String("hello");
[Link](a == b); // true (same literal, same
pool reference)
[Link](a == c); // FALSE (c is a new object in
heap)
[Link]([Link](c)); // true (ALWAYS use equals()
for strings!)
[Link]([Link]("HELLO")); // true
// RULE: NEVER use == to compare String content. Always use
.equals()
// ── STRING FORMATTING ────────────────────────────────────────────
double gpa = 3.75;
String report = [Link]("Student: %-15s GPA: %.2f", "Kofi",
gpa);
[Link](report); // Student: Kofi GPA: 3.75
A mutable sequence of characters. Unlike String, StringBuffer allows
modification without creating new objects. Use it when you need to
StringBuffer
build or modify strings in a loop. StringBuilder is the non-thread-safe
(faster) alternative.
JAVA
// ── WHY StringBuffer? Performance comparison ─────────────────────
// BAD approach with String (creates 10,000 objects!)
String result = "";
for (int i = 0; i < 10000; i++) {
result += i; // each + creates a NEW String — very slow!
}
// GOOD approach with StringBuilder (single mutable object)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
[Link](i); // modifies the SAME object — very fast!
}
String result2 = [Link](); // convert to String when done
// ── StringBuffer METHODS
──────────────────────────────────────────
StringBuffer buffer = new StringBuffer("Hello");
[Link](" World"); // Hello World
[Link](5, ","); // Hello, World
[Link](7, 12, "Java"); // Hello, Java
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 37
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
[Link](5, 6); // Hello Java
[Link](); // avaJ olleH
[Link]([Link]()); // avaJ olleH
[Link]([Link]()); // 10
[Link]([Link](0)); // a
5.2 Wrapper Classes — Encapsulating Primitives
Java has two categories of types: primitive types (int, double, boolean, char...) and reference types
(objects). Wrapper classes wrap primitive values in objects, enabling them to be used where objects
are required (e.g., in collections).
Primitive Type Wrapper Class
int Integer
double Double
boolean Boolean
char Character
long Long
float Float
byte Byte
short Short
JAVA
// ── AUTOBOXING & UNBOXING (Java 5+) ──────────────────────────────
// Java automatically converts between primitives and wrappers
int primitiveInt = 42;
Integer wrapperInt = primitiveInt; // AUTOBOXING (primitive →
wrapper)
int backToPrimitive = wrapperInt; // UNBOXING (wrapper →
primitive)
// ── USEFUL WRAPPER METHODS ───────────────────────────────────────
// Parsing strings to numbers
int age = [Link]("25"); // "25" → 25
double salary = [Link]("4500.50"); // "4500.50" →
4500.50
boolean flag = [Link]("true"); // "true" → true
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 38
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
// Converting numbers to strings
String numStr = [Link](42); // 42 → "42"
String dblStr = [Link](3.14); // 3.14 → "3.14"
// Constants
[Link](Integer.MAX_VALUE); // 2147483647
[Link](Integer.MIN_VALUE); // -2147483648
[Link](Double.MAX_VALUE); // 1.7976931348623157E308
// Checking if string is numeric (useful for input validation)
try {
int n = [Link]("hello"); // throws
NumberFormatException
} catch (NumberFormatException e) {
[Link]("Input is not a valid integer");
}
5.3 ArrayList, LinkedList, and Vector
Arrays in Java have a fixed size — once created, you cannot add or remove elements. The
Collections Framework provides dynamic, resizable alternatives.
Figure: Java Collections Framework — List, Set, Map, Queue
JAVA
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 39
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
import [Link].*;
public class CollectionsDemo {
public static void main(String[] args) {
// ── ARRAYLIST
─────────────────────────────────────────────
// Dynamic array — fast random access by index, slow
insert/delete in middle
ArrayList<String> students = new ArrayList<>();
[Link]("Kofi Mensah"); // add to end
[Link]("Ama Asante");
[Link]("Kwame Boateng");
[Link](0, "First Student"); // insert at index 0
[Link]([Link](0)); // First Student
[Link]([Link]()); // 4
[Link]([Link]("Kofi Mensah")); //
true
[Link]([Link]("Ama Asante")); // 2
[Link]("Ama Asante"); // remove by value
[Link](0); // remove by index
[Link](0, "Kofi Updated"); // replace element
// Iterating
for (String student : students) {
[Link](student);
}
// Sorting
[Link](students); // alphabetical
[Link](students, (a, b) -> // custom sort
[Link](b));
// ── LINKEDLIST
────────────────────────────────────────────
// Doubly-linked list — fast insert/delete at ends, slow
random access
LinkedList<Integer> queue = new LinkedList<>();
[Link](10); // add to front
[Link](20); // add to back
[Link](30);
[Link]([Link]()); // 10
[Link]([Link]()); // 30
[Link](); // removes 10
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 40
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
// ── VECTOR ───────────────────────────────────────────────
// Like ArrayList but thread-safe (synchronized)
// Use in multi-threaded programs when multiple threads
modify the list
Vector<String> threadSafeList = new Vector<>();
[Link]("Thread-safe item");
[Link]([Link]()); // initial
capacity
}
}
Collection Best Used When
ArrayList You need fast index access (get(i)) and mostly add/remove from
end
LinkedList You need fast insert/delete at the front or middle; used as
queue/deque
Vector Same as ArrayList but needed in a multi-threaded environment
(thread-safe)
HashSet You need a collection with NO duplicates and order does not
matter
TreeSet No duplicates AND elements must be kept in sorted order
HashMap You need key→value pairs with fast lookup by key (O(1) average)
TreeMap Key→value pairs that must be kept in sorted key order
5.4 HashMap and the Collections Framework
JAVA
import [Link].*;
public class HashMapDemo {
public static void main(String[] args) {
// ── HASHMAP: key → value pairs
────────────────────────────
HashMap<String, Integer> grades = new HashMap<>();
// put(key, value) — add or update
[Link]("Kofi", 85);
[Link]("Ama", 92);
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 41
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
[Link]("Kwame", 78);
[Link]("Kofi", 88); // UPDATE — replaces 85 with 88
// get(key) — retrieve value
[Link]([Link]("Ama")); // 92
[Link]([Link]("Unknown")); // null (key
not found)
[Link]([Link]("X", 0)); // 0
(default)
// Checking
[Link]([Link]("Kofi")); // true
[Link]([Link](92)); // true
[Link]([Link]()); // 3
// Remove
[Link]("Kwame");
// ── ITERATING A HASHMAP
───────────────────────────────────
// Method 1: iterate over entries (key + value)
for ([Link]<String, Integer> entry : [Link]()) {
[Link]([Link]() + " → " +
[Link]());
}
// Method 2: iterate over keys only
for (String key : [Link]()) {
[Link](key + ": " + [Link](key));
}
// Method 3: forEach with lambda (modern Java)
[Link]((name, grade) ->
[Link]("%-10s %d%n", name, grade));
// ── USEFUL Collections UTILITY METHODS ───────────────────
List<Integer> nums = [Link](3, 1, 4, 1, 5, 9, 2, 6);
[Link]([Link](nums)); // 9
[Link]([Link](nums)); // 1
[Link]([Link](nums, 1)); // 2
List<Integer> mutableNums = new ArrayList<>(nums);
[Link](mutableNums); // [1, 1, 2, 3, 4, 5, 6,
9]
[Link](mutableNums); // [9, 6, 5, 4, 3, 2, 1,
1]
[Link](mutableNums); // random order
}
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 42
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 43
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
UNIT 6
I/O Streams, Files & Serialization
Reading, writing, and persisting data
6.1 File I/O Streams
Java's I/O system is built around streams — sequences of data flowing either from a source (input
stream) or to a destination (output stream). There are two stream families: byte streams for binary
data, and character streams for text.
Stream Type Classes & Use
Byte Input Stream InputStream, FileInputStream — read raw bytes (images,
audio)
Byte Output Stream OutputStream, FileOutputStream — write raw bytes
Character Input Reader, FileReader, BufferedReader — read text characters
Character Output Writer, FileWriter, BufferedWriter, PrintWriter — write text
Scanner Convenient text parsing from files, console, strings
BufferedReader Wraps another reader for efficient line-by-line reading
JAVA
import [Link].*;
import [Link];
public class FileIODemo {
// ── WRITING TO A FILE
─────────────────────────────────────────
public static void writeToFile(String filename) {
// try-with-resources: PrintWriter is closed automatically
try (PrintWriter writer = new PrintWriter(new
FileWriter(filename))) {
[Link]("CTR214: Object-Oriented Programming");
[Link]("Student: Kofi Mensah");
[Link]("Grade: A");
[Link]("GPA: %.2f%n", 3.85);
[Link]("File written successfully: " +
filename);
} catch (IOException e) {
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 44
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
[Link]("Error writing file: " +
[Link]());
}
}
// ── READING FROM A FILE (line by line) ───────────────────────
public static void readFromFile(String filename) {
try (BufferedReader reader = new BufferedReader(new
FileReader(filename))) {
String line;
int lineNum = 1;
while ((line = [Link]()) != null) {
[Link](lineNum + ": " + line);
lineNum++;
}
} catch (FileNotFoundException e) {
[Link]("File not found: " + filename);
} catch (IOException e) {
[Link]("Read error: " + [Link]());
}
}
// ── READING WITH SCANNER
──────────────────────────────────────
public static void readWithScanner(String filename) {
try (Scanner sc = new Scanner(new File(filename))) {
while ([Link]()) {
[Link]([Link]());
}
} catch (FileNotFoundException e) {
[Link]("File not found!");
}
}
// ── APPENDING TO FILE
─────────────────────────────────────────
public static void appendToFile(String filename, String text) {
try (FileWriter fw = new FileWriter(filename, true); // true
= append mode
PrintWriter pw = new PrintWriter(fw)) {
[Link](text);
} catch (IOException e) {
[Link]("Append error: " + [Link]());
}
}
public static void main(String[] args) {
writeToFile("[Link]");
readFromFile("[Link]");
appendToFile("[Link]", "New student added");
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 45
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
}
}
6.2 Object Serialization
The process of converting an object's state into a byte stream so it
Serialization can be saved to a file or sent over a network. Deserialization is the
reverse — reconstructing the object from the byte stream.
Serialization allows you to save program state to disk and restore it later — like saving a game or
persisting user preferences between application runs.
JAVA
import [Link].*;
// ── STEP 1: Make the class Serializable ──────────────────────────
// Implement Serializable marker interface (no methods to implement)
public class Student implements Serializable {
// serialVersionUID ensures compatibility when class changes
private static final long serialVersionUID = 1L;
private String name;
private int age;
private double gpa;
// transient fields are NOT serialized (e.g., passwords,
calculated fields)
private transient String sessionToken;
public Student(String name, int age, double gpa) {
[Link] = name; [Link] = age; [Link] = gpa;
}
@Override
public String toString() {
return [Link]("Student{name='%s', age=%d, gpa=%.2f}",
name, age, gpa);
}
}
// ── STEP 2: Serialize (save to file) ─────────────────────────────
public class SerializeDemo {
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 46
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
public static void saveStudent(Student s, String filename) {
try (ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(filename))) {
[Link](s); // serialize the object
[Link]("Saved: " + s);
} catch (IOException e) {
[Link]("Save error: " + [Link]());
}
}
// ── STEP 3: Deserialize (load from file) ─────────────────────
public static Student loadStudent(String filename) {
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream(filename))) {
Student s = (Student) [Link](); // deserialize
[Link]("Loaded: " + s);
return s;
} catch (IOException | ClassNotFoundException e) {
[Link]("Load error: " + [Link]());
return null;
}
}
public static void main(String[] args) {
Student s = new Student("Kofi Mensah", 21, 3.85);
saveStudent(s, "[Link]");
// Later — possibly in a completely different run of the
program:
Student loaded = loadStudent("[Link]");
[Link](loaded); // Student{name='Kofi Mensah',
age=21, gpa=3.85}
}
}
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 47
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
UNIT 7
Copying, Cloning & Object Duplication
Shallow copy vs deep copy — a critical concept
7.1 Reference Assignment vs Object Copying
When you assign one object variable to another (Student b = a), you are NOT copying the object —
you are copying the reference (memory address). Both variables now point to the SAME object.
Changes through one variable affect the other.
JAVA
// ── REFERENCE COPY (not a real copy) ─────────────────────────────
Student a = new Student("Kofi", 21, 3.8);
Student b = a; // b and a point to the SAME object
[Link]("Ama"); // changes the ONLY object in memory
[Link]([Link]()); // "Ama" — a was changed too!
[Link](a == b); // true — same object reference
// ════════════════════════════════════════════════════════════════
// ── SHALLOW COPY ─────────────────────────────────────────────────
// Copies field values — but if a field is a reference type, the
// copy and original SHARE the same referenced object
public class Address implements Cloneable {
String city;
String country;
public Address(String city, String country) {
[Link] = city; [Link] = country;
}
}
public class PersonShallow implements Cloneable {
String name;
int age;
Address address; // reference type field
public PersonShallow(String name, int age, Address address) {
[Link] = name; [Link] = age; [Link] = address;
}
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 48
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
// [Link]() performs SHALLOW copy by default
@Override
public PersonShallow clone() {
try { return (PersonShallow) [Link](); }
catch (CloneNotSupportedException e) { throw new
RuntimeException(e); }
}
}
// PersonShallow p1 = new PersonShallow("Kofi", 21, new
Address("Accra","Ghana"));
// PersonShallow p2 = [Link](); // shallow copy
//
// [Link] = "Ama"; // OK: primitives/Strings are independent
// [Link] = 22;
//
// [Link] = "Kumasi"; // DANGER: [Link] is ALSO
now Kumasi!
// // Because p1 and p2 share the SAME Address object
// ── DEEP COPY
─────────────────────────────────────────────────────
// Clone ALL referenced objects recursively — complete independence
public class PersonDeep implements Cloneable {
String name;
int age;
Address address;
public PersonDeep(String name, int age, Address address) {
[Link] = name; [Link] = age; [Link] = address;
}
@Override
public PersonDeep clone() {
try {
PersonDeep copy = (PersonDeep) [Link]();
// DEEP: create a NEW Address object for the copy
[Link] = new Address([Link],
[Link]);
return copy;
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
}
// Now: [Link] = "Kumasi" does NOT affect [Link]
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 49
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
// p1 and p2 are completely independent objects
Copy Type What Gets Copied
Reference Assignment (=) Only the memory address — both variables point to the SAME
object
Shallow Copy ([Link]()) Field values — but reference fields share the same underlying
objects
Deep Copy (manual) Everything is duplicated — new objects created for all reference
fields
Copy Constructor A constructor that takes another object of the same type and
copies all fields (deep copy approach)
JAVA
// ── COPY CONSTRUCTOR pattern (often preferred over clone())
───────
public class BankAccount {
private String holder;
private double balance;
private List<String> transactions; // reference type
// Normal constructor
public BankAccount(String holder, double balance) {
[Link] = holder;
[Link] = balance;
[Link] = new ArrayList<>();
}
// COPY CONSTRUCTOR — takes another BankAccount and deep-copies
it
public BankAccount(BankAccount other) {
[Link] = [Link]; // String is immutable, safe
to share
[Link] = [Link]; // primitive, always
independent
// Deep copy the list
[Link] = new ArrayList<>([Link]);
}
}
// Usage:
// BankAccount original = new BankAccount("Kofi", 500.0);
// BankAccount copy = new BankAccount(original); // copy
constructor
// copy and original are completely independent
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 50
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 51
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
UNIT 8
Control Structures & Statements
Conditionals, loops, and program flow in Java
8.1 Conditional Statements
Control structures determine which code executes and in what order. Java's conditional statements
are nearly identical to C and C++, making this unit accessible to students with prior programming
experience.
JAVA
// ── IF / ELSE IF / ELSE ──────────────────────────────────────────
int score = 75;
if (score >= 90) {
[Link]("Grade: A");
} else if (score >= 80) {
[Link]("Grade: B");
} else if (score >= 70) {
[Link]("Grade: C");
} else if (score >= 60) {
[Link]("Grade: D");
} else {
[Link]("Grade: F");
}
// Output: Grade: C
// ── TERNARY OPERATOR (compact if-else for simple assignments)
─────
String result = score >= 50 ? "Pass" : "Fail";
[Link](result); // Pass
// ── SWITCH STATEMENT ─────────────────────────────────────────────
String day = "Monday";
switch (day) {
case "Monday":
case "Tuesday":
case "Wednesday":
case "Thursday":
case "Friday":
[Link](day + " is a weekday");
break;
case "Saturday":
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 52
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
case "Sunday":
[Link](day + " is a weekend");
break;
default:
[Link]("Unknown day");
}
// ── SWITCH EXPRESSION (Java 14+) — cleaner syntax ────────────────
String category = switch (day) {
case "Saturday", "Sunday" -> "Weekend";
default -> "Weekday";
};
[Link](category); // Weekday
8.2 Loops and Iterations
JAVA
// ── FOR LOOP — when you know how many iterations
──────────────────
for (int i = 0; i < 5; i++) {
[Link](i + " "); // 0 1 2 3 4
}
// ── ENHANCED FOR-EACH — iterating collections/arrays ────────────
String[] languages = {"Java", "Python", "C++", "JavaScript"};
for (String lang : languages) {
[Link](lang);
}
// ── WHILE LOOP — when condition drives the loop
───────────────────
int count = 0;
while (count < 5) {
[Link](count + " ");
count++;
}
// ── DO-WHILE — executes body AT LEAST ONCE, then checks condition
─
int num;
Scanner sc = new Scanner([Link]);
do {
[Link]("Enter a positive number: ");
num = [Link]();
} while (num <= 0); // repeats until valid input
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 53
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
// ── BREAK and CONTINUE ───────────────────────────────────────────
// break: immediately exits the loop
// continue: skips the current iteration and moves to the next
for (int i = 0; i < 10; i++) {
if (i == 3) continue; // skip 3
if (i == 7) break; // stop at 7
[Link](i + " ");
}
// Output: 0 1 2 4 5 6
// ── NESTED LOOPS — multiplication table example ──────────────────
[Link]("\nMultiplication Table:");
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 5; j++) {
[Link]("%4d", i * j);
}
[Link]();
}
// 1 2 3 4 5
// 2 4 6 8 10
// 3 6 9 12 15
// 4 8 12 16 20
// 5 10 15 20 25
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 54
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
UNIT 9
GUI Programming with Swing & JavaFX
Building graphical user interfaces in Java
9.1 Event-Driven Programming
A programming paradigm where the flow of the program is
Event-Driven determined by events — user actions such as button clicks, key
Programming presses, mouse movements, or system-generated events like timers.
The program waits for events and responds to them.
Traditional programs run top-to-bottom in a predictable sequence. GUI programs are
fundamentally different — they sit idle until the user does something (clicks a button, types text),
then respond appropriately. This requires a new way of thinking about program structure.
Event-Driven Concept Java Implementation
Event Source A GUI component (JButton, JTextField) that generates events
when interacted with
Event Object An object (ActionEvent, MouseEvent, KeyEvent) that describes
what happened
Event Listener An interface (ActionListener, MouseListener) that receives and
handles events
Event Handler The method (actionPerformed(), mouseClicked()) that contains
your response code
Registration Calling addActionListener() to connect a listener to a source
component
9.2 Swing Components
Swing is Java's built-in GUI toolkit. It provides a rich set of components (called widgets) that work
across all platforms with a consistent appearance.
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 55
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
Figure: Swing Component Hierarchy — JFrame contains JPanels which contain widgets
Component Purpose & Common Properties
JFrame The main application window. setTitle(), setSize(),
setDefaultCloseOperation()
JPanel An invisible container for grouping components. setLayout()
JButton Clickable button. setText(), addActionListener()
JTextField Single-line text input. getText(), setText(), setColumns()
JTextArea Multi-line text area. append(), setLineWrap()
JLabel Non-editable text or image display. setText(), setFont(),
setForeground()
JPasswordField Like JTextField but masks characters. getPassword()
JComboBox Dropdown selector. addItem(), getSelectedItem()
JCheckBox Boolean toggle. isSelected(), setSelected()
JRadioButton One of mutually exclusive choices. Use ButtonGroup
JMenuBar/JMenu/JMenuItem Menu system. setJMenuBar(), add()
JScrollPane Adds scrollbars to any component. new
JScrollPane(component)
9.3 Complete Swing Application — Student Grade Viewer
This complete example demonstrates all major Swing concepts: window setup, layout managers,
event handling, and data display.
JAVA
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 56
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
import [Link].*;
import [Link].*;
import [Link].*;
import [Link];
// ── DATA MODEL (application core) ────────────────────────────────
class StudentRecord {
private String name;
private int score;
public StudentRecord(String name, int score) {
[Link] = name; [Link] = score;
}
public String getGrade() {
if (score >= 90) return "A";
if (score >= 80) return "B";
if (score >= 70) return "C";
if (score >= 60) return "D";
return "F";
}
@Override
public String toString() {
return [Link]("%-20s %3d %s", name, score,
getGrade());
}
}
// ── GUI VIEW (user interface)
─────────────────────────────────────
public class GradeApp extends JFrame {
// Components
private JTextField nameField, scoreField;
private JTextArea outputArea;
private JButton addButton, clearButton, statsButton;
private JLabel statusLabel;
// Data
private ArrayList<StudentRecord> records = new ArrayList<>();
public GradeApp() {
setupWindow();
setupComponents();
setupListeners();
}
private void setupWindow() {
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 57
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
setTitle("CTR214 — Student Grade Manager");
setSize(550, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null); // centre on screen
setLayout(new BorderLayout(10, 10));
getContentPane().setBackground(new Color(240, 244, 248));
}
private void setupComponents() {
// ── NORTH: Input Panel
────────────────────────────────────
JPanel inputPanel = new JPanel(new GridBagLayout());
[Link](new Color(13, 31, 60));
[Link]([Link](16, 16,
16, 16));
GridBagConstraints gc = new GridBagConstraints();
[Link] = new Insets(4, 4, 4, 4);
[Link] = [Link];
JLabel nameLabel = new JLabel("Student Name:");
JLabel scoreLabel = new JLabel("Score (0-100):");
[Link]([Link]);
[Link]([Link]);
nameField = new JTextField(20);
scoreField = new JTextField(5);
addButton = new JButton("Add Student");
clearButton = new JButton("Clear All");
statsButton = new JButton("Show Stats");
[Link](new Color(180, 140, 46));
[Link]([Link]);
[Link](new Font("Arial", [Link], 12));
[Link]=0; [Link]=0; [Link](nameLabel, gc);
[Link]=1; [Link]=0; [Link]=1;
[Link](nameField, gc);
[Link]=0; [Link]=1; [Link]=0;
[Link](scoreLabel, gc);
[Link]=1; [Link]=1; [Link](scoreField, gc);
JPanel buttonPanel = new JPanel(new
FlowLayout([Link], 8, 4));
[Link](new Color(13, 31, 60));
[Link](addButton);
[Link](clearButton);
[Link](statsButton);
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 58
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
[Link]=0; [Link]=2; [Link]=2;
[Link](buttonPanel, gc);
add(inputPanel, [Link]);
// ── CENTRE: Output Area
───────────────────────────────────
outputArea = new JTextArea();
[Link](new Font("Courier New", [Link], 13));
[Link](false);
[Link](new Color(30, 30, 46));
[Link](new Color(224, 224, 255));
[Link]("Name Score Grade\n");
[Link]("-".repeat(36) + "\n");
add(new JScrollPane(outputArea), [Link]);
// ── SOUTH: Status Bar
─────────────────────────────────────
statusLabel = new JLabel("Ready — enter student details
above");
[Link]([Link](6, 12,
6, 12));
[Link](new Font("Arial", [Link], 12));
add(statusLabel, [Link]);
}
private void setupListeners() {
// Add Button — ActionListener with anonymous inner class
[Link](new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
addStudent(); // call method defined below
}
});
// Same thing using Lambda (Java 8+) — much cleaner
[Link](e -> clearAll());
[Link](e -> showStats());
// Allow pressing Enter in scoreField to add student
[Link](e -> addStudent());
}
private void addStudent() {
String name = [Link]().trim();
String scoreStr = [Link]().trim();
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 59
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
// Input validation
if ([Link]()) {
showError("Please enter a student name");
return;
}
try {
int score = [Link](scoreStr);
if (score < 0 || score > 100) throw new
IllegalArgumentException();
StudentRecord record = new StudentRecord(name, score);
[Link](record);
[Link](record + "\n");
[Link]("Added: " + name + " (" +
[Link]() + " total)");
// Clear inputs for next entry
[Link]("");
[Link]("");
[Link]();
} catch (NumberFormatException ex) {
showError("Score must be a number (e.g. 85)");
} catch (IllegalArgumentException ex) {
showError("Score must be between 0 and 100");
}
}
private void clearAll() {
int confirm = [Link](this,
"Clear all " + [Link]() + " records?",
"Confirm Clear", JOptionPane.YES_NO_OPTION);
if (confirm == JOptionPane.YES_OPTION) {
[Link]();
[Link]("Name Score
Grade\n");
[Link]("-".repeat(36) + "\n");
[Link]("All records cleared");
}
}
private void showStats() {
if ([Link]()) { showError("No records yet!");
return; }
double total = 0; int highest = 0; int lowest = 100;
String topStudent = "", bottomStudent = "";
for (StudentRecord r : records) { // polymorphic iteration
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 60
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
// Use reflection to get score — or add a getter (better
practice)
// For this demo we parse from toString()
// In real code: expose getScore() getter
}
[Link](this,
[Link]("Total Students: %d\nAverage Score:
computed via getScore()",
[Link]()),
"Statistics", JOptionPane.INFORMATION_MESSAGE);
}
private void showError(String msg) {
[Link](this, msg, "Input Error",
JOptionPane.ERROR_MESSAGE);
[Link]("Error: " + msg);
}
public static void main(String[] args) {
// Always create GUI on the Event Dispatch Thread (EDT)
[Link](() -> {
new GradeApp().setVisible(true);
});
}
}
THE EVENT DISPATCH THREAD (EDT)
Swing is NOT thread-safe. All GUI creation and updates must happen on the EDT — a special
thread Swing uses for all UI operations. Always use [Link](() -> { ... }) to
launch your GUI. Updating the GUI from any other thread causes random, hard-to-debug
bugs.
9.4 Layout Managers
Layout managers automatically determine the position and size of components within a container.
Never use absolute positioning (null layout) in real applications — it breaks when the window is
resized or on different screen resolutions.
Layout Manager Behaviour & When to Use
FlowLayout (default for Places components left-to-right, wrapping to next line. Good for
JPanel) toolbars and button rows.
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 61
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
BorderLayout (default for Divides container into NORTH, SOUTH, EAST, WEST, CENTER. Great
JFrame) for main window layout.
GridLayout Equal-sized grid of rows and columns. Good for number pads,
calculator buttons.
GridBagLayout Most powerful and flexible — each component has individual
constraints. Steep learning curve.
BoxLayout Arranges components in a single row or column. Good for vertical
lists.
CardLayout Stacks multiple panels — show one at a time. Good for wizard-style
UIs or tab simulation.
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 62
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
UNIT 10
Application Design & Mini-Project
Two-layer architecture and a complete Java application
10.1 Two-Layer Architecture
A design pattern that separates an application into two distinct
Two-Layer layers: (1) the Application Core (business logic, data, rules) and (2) the
Architecture User Interface (GUI/presentation layer). The core must function
independently of the interface.
This separation is one of the most important principles in software engineering. It means you can
change the entire user interface (from Swing to JavaFX to a web app) without touching the business
logic. It also makes the core independently testable.
Application Core (Layer 1) User Interface (Layer 2)
Contains all business rules and logic Contains only presentation and interaction
code
Works without any GUI — pure Java Depends on the core but core does NOT
depend on UI
Independent, testable with unit tests Changes without affecting core behaviour
Classes: Student, GradeCalculator, DataStore Classes: GradeApp (JFrame), StudentPanel,
MenuBar
No import [Link] in this layer Uses core objects via their public methods only
The communication rule: the Core layer can have NO reference to any UI class. The UI layer creates
core objects, calls their methods, and displays results. This is dependency direction — UI depends
on Core, never the other way.
10.2 Mini-Project — Complete Student Grade Management System
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 63
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
This mini-project brings together every concept from the course: OOP design, encapsulation,
inheritance, exceptions, collections, file I/O, and a Swing GUI with clean two-layer architecture.
JAVA
// ════════════════════════════════════════════════════════════════════
// LAYER 1: APPLICATION CORE
// ════════════════════════════════════════════════════════════════════
// ── [Link] (Entity) ─────────────────────────────────────────
package core;
import [Link];
import [Link];
import [Link];
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
private static int nextId = 1000;
private final int studentId;
private String name;
private String programme;
private List<Double> scores;
public Student(String name, String programme) {
[Link] = nextId++;
[Link] = name;
[Link] = programme;
[Link] = new ArrayList<>();
}
public void addScore(double score) {
if (score < 0 || score > 100)
throw new IllegalArgumentException("Score must be 0-100: "
+ score);
[Link](score);
}
public double getAverage() {
if ([Link]()) return 0;
return
[Link]().mapToDouble(Double::doubleValue).average().orElse(0);
}
public String getGrade() {
double avg = getAverage();
if (avg >= 90) return "A";
if (avg >= 80) return "B";
if (avg >= 70) return "C";
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 64
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
if (avg >= 60) return "D";
return "F";
}
// Getters
public int getStudentId() { return studentId; }
public String getName() { return name; }
public String getProgramme() { return programme; }
public List<Double> getScores() { return new ArrayList<>(scores);
} // defensive copy
// Setters with validation
public void setName(String name) {
if (name == null || [Link]().isEmpty())
throw new IllegalArgumentException("Name cannot be empty");
[Link] = [Link]();
}
@Override
public String toString() {
return [Link]("[%d] %-20s %-25s Avg: %5.1f Grade: %s",
studentId, name, programme, getAverage(),
getGrade());
}
}
// ── [Link] (Business Logic) ────────────────────────────
package core;
import [Link].*;
import [Link].*;
public class GradeSystem {
private List<Student> students = new ArrayList<>();
private static final String SAVE_FILE = "[Link]";
// CRUD operations
public void addStudent(Student s) {
if (s == null) throw new IllegalArgumentException("Student
cannot be null");
[Link](s);
}
public boolean removeStudent(int id) {
return [Link](s -> [Link]() == id);
}
public Optional<Student> findById(int id) {
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 65
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
return [Link]().filter(s -> [Link]() ==
id).findFirst();
}
public List<Student> getAllStudents() {
return [Link](students);
}
// Analytics — pure business logic, NO GUI code
public double getClassAverage() {
return
[Link]().mapToDouble(Student::getAverage).average().orElse(0);
}
public Student getTopStudent() {
return [Link]()
.max([Link](Student::getAverage))
.orElse(null);
}
public Map<String, Long> getGradeDistribution() {
Map<String, Long> dist = new TreeMap<>();
for (Student s : students) {
[Link]([Link](), 1L, Long::sum);
}
return dist;
}
// Persistence — save/load from file
public void saveToFile() throws IOException {
try (ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(SAVE_FILE))) {
[Link](students);
}
}
@SuppressWarnings("unchecked")
public void loadFromFile() throws IOException,
ClassNotFoundException {
File f = new File(SAVE_FILE);
if (![Link]()) return;
try (ObjectInputStream ois = new ObjectInputStream(new
FileInputStream(f))) {
students = (List<Student>) [Link]();
}
}
}
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 66
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
JAVA
//
════════════════════════════════════════════════════════════════════
// LAYER 2: USER INTERFACE
//
════════════════════════════════════════════════════════════════════
// ── [Link] (GUI — depends on core, core does NOT depend on
GUI)
package ui;
import core.*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link];
public class MainApp extends JFrame {
private GradeSystem system = new GradeSystem(); // core
dependency
// UI Components
private JTextArea display;
private JTextField nameField, programmeField;
private JTextField idField, scoreField;
private JLabel statusBar;
public MainApp() {
loadData(); // load saved data from file
buildUI(); // create the user interface
refreshDisplay(); // show current data
}
private void buildUI() {
setTitle("CTR214 Mini-Project — Grade Management System");
setSize(700, 580);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setLayout(new BorderLayout(8, 8));
// ── North: Menu Bar
───────────────────────────────────────
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
JMenuItem saveItem = new JMenuItem("Save");
JMenuItem exitItem = new JMenuItem("Exit");
[Link](e -> saveData());
[Link](e -> [Link](0));
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 67
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
[Link](saveItem); [Link]();
[Link](exitItem);
[Link](fileMenu);
JMenu reportsMenu = new JMenu("Reports");
JMenuItem statsItem = new JMenuItem("Class Statistics");
[Link](e -> showStats());
[Link](statsItem);
[Link](reportsMenu);
setJMenuBar(menuBar);
// ── West: Add Student Panel
───────────────────────────────
JPanel addPanel = new JPanel(new GridBagLayout());
[Link](new Color(13, 31, 60));
[Link]([Link](
[Link](new Color(180,140,46),
2),
"Add Student",
[Link],
[Link],
new Font("Arial", [Link], 12),
new Color(180,140,46)));
nameField = new JTextField(15);
programmeField = new JTextField(15);
JButton addBtn = new JButton("Add");
[Link](new Color(26, 92, 50));
[Link]([Link]);
[Link](e -> addStudent());
GridBagConstraints g = new GridBagConstraints();
[Link] = new Insets(6,8,6,8); [Link] =
[Link];
addLabelField(addPanel, "Name:", nameField, g, 0,
[Link]);
addLabelField(addPanel, "Programme:", programmeField, g, 1,
[Link]);
[Link]=0; [Link]=2; [Link]=2; [Link](addBtn,
g);
// ── East: Add Score Panel
─────────────────────────────────
JPanel scorePanel = new JPanel(new GridBagLayout());
[Link](new Color(26, 58, 92));
[Link]([Link](
[Link](new Color(14,90,104), 2),
"Add Score",
[Link],
[Link],
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 68
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
new Font("Arial", [Link], 12),
new Color(14, 90, 104)));
idField = new JTextField(10);
scoreField = new JTextField(5);
JButton scoreBtn = new JButton("Add Score");
[Link](new Color(14, 90, 104));
[Link]([Link]);
[Link](e -> addScore());
GridBagConstraints g2 = new GridBagConstraints();
[Link] = new Insets(6,8,6,8); [Link] =
[Link];
addLabelField(scorePanel, "Student ID:", idField, g2, 0,
[Link]);
addLabelField(scorePanel, "Score:", scoreField, g2, 1,
[Link]);
[Link]=0; [Link]=2; [Link]=2;
[Link](scoreBtn, g2);
// ── Centre: Display
───────────────────────────────────────
display = new JTextArea();
[Link](new Font("Courier New", [Link], 12));
[Link](false);
[Link](new Color(30, 30, 46));
[Link](new Color(224, 224, 255));
// ── South: Status Bar
─────────────────────────────────────
statusBar = new JLabel("Ready");
[Link]([Link](4,10,4,10));
JPanel sidePanel = new JPanel(new GridLayout(1, 2, 8, 0));
[Link](addPanel); [Link](scorePanel);
[Link](new Color(240, 244, 248));
add(sidePanel, [Link]);
add(new JScrollPane(display), [Link]);
add(statusBar, [Link]);
}
private void addLabelField(JPanel p, String label, JTextField
field,
GridBagConstraints g, int row, Color
fg) {
JLabel l = new JLabel(label); [Link](fg);
[Link]=0; [Link]=row; [Link](l, g);
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 69
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
[Link]=1; [Link](field, g);
}
// ── ACTIONS (connect UI to core)
──────────────────────────────
private void addStudent() {
String name = [Link]().trim();
String prog = [Link]().trim();
if ([Link]() || [Link]()) {
status("Error: Enter both name and programme"); return;
}
Student s = new Student(name, prog);
[Link](s);
[Link](""); [Link]("");
refreshDisplay();
status("Added: " + name + " (ID: " + [Link]() +
")");
}
private void addScore() {
try {
int id = [Link]([Link]().trim());
double sc =
[Link]([Link]().trim());
Student found = [Link](id)
.orElseThrow(() -> new IllegalArgumentException("ID
" + id + " not found"));
[Link](sc);
[Link](""); [Link]("");
refreshDisplay();
status("Score " + sc + " added to " + [Link]());
} catch (NumberFormatException e) {
status("Error: Enter valid numeric ID and score");
} catch (Exception e) {
status("Error: " + [Link]());
}
}
private void refreshDisplay() {
StringBuilder sb = new StringBuilder();
[Link]([Link]("%-6s %-20s %-25s %-8s %s%n",
"ID","Name","Programme","Average","Grade"));
[Link]("─".repeat(70)).append("\n");
for (Student s : [Link]()) {
[Link](s).append("\n");
}
[Link]("─".repeat(70)).append("\n");
[Link]([Link]("Total Students: %d | Class
Average: %.1f%n",
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 70
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
[Link]().size(),
[Link]()));
[Link]([Link]());
}
private void showStats() {
if ([Link]().isEmpty()) {
[Link](this, "No students yet!");
return;
}
StringBuilder sb = new StringBuilder("CLASS STATISTICS\n" +
"─".repeat(30) + "\n");
[Link]([Link]("Total students: %d%n",
[Link]().size()));
[Link]([Link]("Class average: %.2f%n",
[Link]()));
Student top = [Link]();
if (top != null) [Link]("Top student:
").append([Link]()).append("\n");
[Link]("\nGrade Distribution:\n");
[Link]().forEach((grade, count) ->
[Link]([Link](" Grade %s: %d student(s)%n",
grade, count)));
[Link](this, [Link](),
"Statistics",
JOptionPane.INFORMATION_MESSAGE);
}
private void saveData() {
try { [Link](); status("Data saved
successfully"); }
catch (IOException e) { status("Save error: " +
[Link]()); }
}
private void loadData() {
try { [Link](); }
catch (Exception e) { /* first run — no file yet */ }
}
private void status(String msg) { [Link](msg); }
public static void main(String[] args) {
[Link](() -> new
MainApp().setVisible(true));
}
}
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 71
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
MINI-PROJECT SUMMARY
This application demonstrates: Encapsulation (private fields with getters/setters),
Inheritance (Student is Serializable), Exception Handling (try-catch on all inputs), Collections
(ArrayList, HashMap for distribution), File I/O (serialization save/load), Swing GUI (JFrame,
JPanel, JButton, JTextArea, JMenuBar), Two-Layer Architecture (core package independent
from ui package).
Quick Reference — Essential Java Facts
Topic Key Facts to Remember
Class declaration public class ClassName { ... } — file name = [Link]
Constructor Same name as class, no return type. Default provided if none
written.
this keyword Refers to current object instance. Use [Link] to distinguish
from parameter.
super keyword Refers to parent class. super() calls parent constructor (must be
first line).
static Belongs to class, not instances. Accessed as [Link]
final Variable: constant (cannot change). Method: cannot override.
Class: cannot extend.
abstract Method: no body (subclass must implement). Class: cannot
instantiate directly.
interface 100% abstract contract. A class can implement multiple
interfaces.
null Default value for all reference types. Access on null causes
NullPointerException.
== vs .equals() == compares references (memory address). .equals() compares
content. ALWAYS use .equals() for String comparison.
ArrayList vs Array ArrayList is dynamic (resizable). Array has fixed size. ArrayList
cannot hold primitives directly.
try-catch-finally try: code that might fail. catch: handle it. finally: always runs
(cleanup).
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 72
CTR214: Object-Oriented Programming JAVA FOCUS
Java Course Notes · Dept. of Computer Science
CTR214 · OOP in Java · Course Notes · © Department of Computer Science Page 73