UML Class Diagrams
IB Syllabus: B3.1 – Design and interpret UML class diagrams showing class structure and relationships.
Table of Contents
- Key Concepts
- Worked Examples
- Quick Check
- Fill in the Blanks
- Spot the Error
- Practice Exercises
- Connections
Key Concepts
What is UML?
UML (Unified Modeling Language) is a standard visual language for designing and documenting software systems. A UML class diagram shows the structure of a class – its name, attributes, and methods – in a three-section box.
Class diagrams are drawn BEFORE writing code. They serve as a blueprint that communicates the design to other developers (or to yourself) without getting lost in syntax details.
The Three-Section Box
Every class is represented as a rectangle divided into three sections:
+---------------------------+
| ClassName | ← Section 1: Class name (centred, bold)
+---------------------------+
| - attribute1: Type | ← Section 2: Attributes (name: type)
| - attribute2: Type |
+---------------------------+
| + method1(params): Return | ← Section 3: Methods (name(params): return)
| + method2(): void |
+---------------------------+
Access Modifier Symbols
UML uses symbols instead of Java keywords to show visibility:
| Symbol | Java keyword | Meaning |
|---|---|---|
- | private | Only accessible within the class |
+ | public | Accessible from any class |
# | protected | Accessible within the class and subclasses |
Every attribute and method in a UML diagram must have an access modifier symbol. In IB exams, missing symbols lose marks. The standard pattern:
-for attributes,+for constructors and public methods.
Attribute Format
Attributes follow the format: visibility name: type
- owner: String
- balance: double
- isActive: boolean
- items: Product[]
Note: the type comes AFTER the name, separated by a colon. This is the opposite of Java syntax (String owner in Java vs owner: String in UML).
Method Format
Methods follow the format: visibility name(parameterTypes): returnType
+ BankAccount(String, double) ← constructor (no return type)
+ getBalance(): double ← getter returns double
+ deposit(double): void ← mutator returns void
+ canWithdraw(double): boolean ← method returns boolean
Constructors are listed with the class name and parameter types but no return type.
Complete Example
Java class:
public class BankAccount {
private String owner;
private double balance;
public BankAccount(String owner, double balance) {
this.owner = owner;
this.balance = balance;
}
public String getOwner() { return owner; }
public double getBalance() { return balance; }
public void deposit(double amount) { ... }
public boolean canWithdraw(double amount) { ... }
}
UML diagram:
+----------------------------------+
| BankAccount |
+----------------------------------+
| - owner: String |
| - balance: double |
+----------------------------------+
| + BankAccount(String, double) |
| + getOwner(): String |
| + getBalance(): double |
| + deposit(double): void |
| + canWithdraw(double): boolean |
+----------------------------------+
Relationship Arrows
UML diagrams also show how classes relate to each other.
Inheritance (is-a) – solid line with a closed triangle pointing to the parent:
+----------+
| Animal | ← parent (superclass)
+----------+
△
|
+----------+
| Dog | ← child (subclass)
+----------+
Read as: “Dog IS-A Animal” – Dog extends Animal.
Aggregation (has-a) – line with an open diamond on the “whole” side:
+----------+ +----------+
| Student |◇------| Address |
+----------+ +----------+
(whole) (part)
Read as: “Student HAS-A Address” – Student contains an Address object as an attribute.
Both in one diagram:
+----------+
| Vehicle |
+----------+
△
|
+----------+ +----------+
| Car |◇------| Engine |
+----------+ +----------+
Car IS-A Vehicle (inheritance) and Car HAS-A Engine (aggregation).
Drawing from Code
To convert Java code to UML:
- Class name goes in section 1
- Instance variables become attributes in section 2 (add
-for private,+for public) - Constructors and methods go in section 3 (add
+for public,-for private) - Flip the type order:
String namein Java becomesname: Stringin UML - Add return types after a colon:
void,String,int,boolean, etc.
Drawing from a Scenario
To convert a scenario description to UML:
- Identify the nouns – these become classes or attributes
- Identify the verbs – these become methods
- Identify relationships – “has a” suggests aggregation, “is a” suggests inheritance
- Decide data types for each attribute
- Decide return types and parameters for each method
In exams, UML diagrams typically carry 2-5 marks. Marks are awarded for: correct class box with three sections [1], correct attributes with types and visibility [1], correct methods with return types [1], correct relationship arrows [1].
Worked Examples
Example 1: Code to UML
Java code:
public class Product {
private String name;
private double price;
private int stock;
public Product(String name, double price, int stock) { ... }
public String getName() { return name; }
public double getPrice() { return price; }
public int getStock() { return stock; }
public boolean isInStock() { return stock > 0; }
public void sell(int quantity) { ... }
private boolean hasEnoughStock(int quantity) { ... }
}
UML:
+------------------------------------+
| Product |
+------------------------------------+
| - name: String |
| - price: double |
| - stock: int |
+------------------------------------+
| + Product(String, double, int) |
| + getName(): String |
| + getPrice(): double |
| + getStock(): int |
| + isInStock(): boolean |
| + sell(int): void |
| - hasEnoughStock(int): boolean |
+------------------------------------+
Notice: hasEnoughStock is - (private) because it is a helper method.
Example 2: Scenario to UML
Scenario: A school library tracks books. Each book has a title, author, ISBN, and whether it is currently on loan. The library can check out and return books.
Step 1: Nouns = Book (class), title, author, ISBN, onLoan (attributes)
Step 2: Verbs = checkOut, returnBook (methods). Also need getters.
Step 3: Data types: title (String), author (String), ISBN (String), onLoan (boolean)
UML:
+-------------------------------+
| Book |
+-------------------------------+
| - title: String |
| - author: String |
| - isbn: String |
| - onLoan: boolean |
+-------------------------------+
| + Book(String, String, String)|
| + getTitle(): String |
| + getAuthor(): String |
| + isOnLoan(): boolean |
| + checkOut(): void |
| + returnBook(): void |
+-------------------------------+
Example 3: Two Classes with Relationship
Scenario: A Library manages an array of Book objects.
+-------------------------------+ +-------------------------------+
| Library | | Book |
+-------------------------------+ +-------------------------------+
| - books: Book[] | | - title: String |
| - name: String | | - author: String |
+-------------------------------+ | - onLoan: boolean |
| + Library(String, int) | +-------------------------------+
| + addBook(Book): void |◇------| + Book(String, String) |
| + findByTitle(String): Book | | + getTitle(): String |
| + countAvailable(): int | | + isOnLoan(): boolean |
+-------------------------------+ | + checkOut(): void |
+-------------------------------+
The diamond (◇) on the Library side shows aggregation: Library HAS Books.
Quick Check
Q1. How is a private double balance written in UML?
Q2. What are the three sections of a UML class diagram?
Q3. Which UML symbol represents inheritance?
Q4. How does a constructor differ from a method in a UML diagram?
Q5. A School contains an array of Student objects. Which UML relationship is this?
Fill in the Blanks
Complete the UML notation rules:
UML Access Modifier Symbols
============================
means private
means public
means protected
UML Attribute Format
====================
visibility :
UML Relationships
=================
△ (closed triangle) =
◇ (open diamond) = Spot the Error
This UML diagram has a notation error. Click the line with the error, then pick the fix.
Pick the correct UML format:
Practice Exercises
Core
- Code to UML – Convert this Java class to a complete UML class diagram:
public class Circle { private double radius; public Circle(double radius) { this.radius = radius; } public double getRadius() { return radius; } public double getArea() { return Math.PI * radius * radius; } public void setRadius(double radius) { if (radius > 0) this.radius = radius; } } -
Scenario to UML – A vet clinic tracks patients. Each patient has a name (String), species (String), age (int), and vaccination status (boolean). The clinic can vaccinate a patient and check if it is vaccinated. Draw the UML diagram.
- Read a UML diagram – Given this UML, write the Java class:
+-------------------------------+ | Song | +-------------------------------+ | - title: String | | - artist: String | | - durationSecs: int | +-------------------------------+ | + Song(String, String, int) | | + getTitle(): String | | + getArtist(): String | | + isLong(): boolean | +-------------------------------+
Extension
-
Two-class diagram – Draw UML for a
Playlistthat contains an array ofSongobjects. Show both classes and the aggregation relationship. The playlist has a name and can add songs, remove by title, and get the total duration. -
Identify relationships – For each pair, state whether the relationship is inheritance (is-a) or aggregation (has-a):
- (a) Car and Engine
- (b) Dog and Animal
- (c) School and Student
- (d) SavingsAccount and BankAccount
Challenge
- Full system design – A hospital needs to track doctors and appointments. Each doctor has a name, specialisation, and a list of appointments. Each appointment has a patient name, date, and duration. Draw the complete UML with both classes, their attributes, methods, and the relationship between them.
Connections
- Prerequisites: Encapsulation – UML
-and+symbols represent the private/public access modifiers - Prerequisites: Access Modifiers – understanding what each visibility level means
- Next: Aggregation – deeper dive into the has-a relationship shown with ◇
- Forward: Inheritance – the is-a relationship shown with △