Unit 4: Class Diagrams: Structure I
Learning Objectives
- Identify and correctly use the three compartments of a UML class
- Write attributes with visibility symbols and types, and operations with signatures
- Model associations between classes with appropriate multiplicity notation
Core Input
Read through each tab before moving to the key concepts.
A UML class is drawn as a rectangle divided into three compartments:
- Top — the class name, centred and in bold. By convention, class names use UpperCamelCase (BookingSystem, Student).
- Middle — attributes (data held by the class). Each attribute is written as:
visibility name : type. Example:- studentId : Integer - Bottom — operations (behaviours the class can perform). Each operation is written as:
visibility name(params) : returnType. Example:+ enrol(c : Course) : Boolean
Visibility symbols:
+public — accessible from anywhere-private — accessible only within the class#protected — accessible within the class and its subclasses~package — accessible within the same package
The middle and bottom compartments can be omitted when the detail is not needed — for example, in early design sketches where class names and relationships are more important.
An association represents a relationship between two classes — one class knows about or uses the other. It is drawn as a solid line between the two class boxes.
- Unidirectional association — an open arrowhead on one end shows that only one class knows about the other. Order → Customer means Order knows about Customer, but not vice versa.
- Bidirectional association — no arrowheads (or one at each end). Both classes know about each other.
- Role names — labels placed near each end of the line naming the role played in the relationship. For example: employer at the Company end, employee at the Person end.
Associations often correspond to attributes — but showing them as lines on the diagram is preferred when the relationship is meaningful and has multiplicity.
Multiplicity specifies how many instances of one class can be associated with one instance of another. It is written at each end of an association line.
| Notation | Meaning | Example |
|---|---|---|
1 | Exactly one | An Order has exactly one Customer |
0..1 | Zero or one (optional) | A Person has zero or one Passport |
1..* | One or more | A Course has one or more Students |
0..* or * | Zero or more (many) | A Student is enrolled in zero or more Courses |
2..5 | Between 2 and 5 | A Team has between 2 and 5 Members |
Multiplicity constraints are enforced at the data level — they describe valid states of the system, not just typical ones.
Key Concepts: Class Notation
Work through each accordion item carefully — class notation is precise and detail matters.
Every UML class box has three horizontal compartments:
- Name compartment — the class name only. Abstract class names are written in italics. No other content belongs here.
-
Attributes compartment — instance variables: data that each object of this
class holds. Format:
visibility name : type [= defaultValue]. Class-level (static) attributes are underlined. -
Operations compartment — methods: behaviours the class can perform.
Format:
visibility name(paramName : paramType) : returnType. A void operation has no return type listed (or listsvoid).
In early design stages, it is common to show only the name compartment. Add attributes and operations as the design becomes more detailed.
Visibility controls which other classes can access an attribute or operation. It is a key tool for encapsulation — hiding implementation details.
-
-private — only code inside this class can read or modify this attribute. This is the default for most attributes — direct access from outside is a design smell. -
+public — any class can call this operation. Typically used for the class's intended interface — its public API. -
#protected — accessible within this class and any subclass. Used when subclasses need to access internal state.
A common convention: attributes are private (-), operations are public (+).
Getter and setter operations provide controlled access to private attributes.
The full attribute syntax is:
visibility name : type [multiplicity] [= defaultValue]
Examples:
- studentId : Integer- email : String- isEnrolled : Boolean = false- grades : Integer[0..*]— a collection of integers
Type names are typically language-neutral in UML: Integer, String, Boolean, Real. If you are modelling closely to a specific language (Java, Python), you may use that language's type names instead.
The full operation syntax is:
visibility name(paramName : paramType, ...) : returnType
Examples:
+ enrol(course : Course) : Boolean+ getName() : String+ setEmail(email : String)— void, no return type shown+ calculateGrade(scores : Integer[*]) : Real
Operations represent what the class can do, not how it does it. You should not include implementation details (loops, conditionals) in the operation signature — those belong in sequence or activity diagrams.
Key Concepts: Associations and Multiplicity
Continue with the remaining key concepts on relationships between classes.
Both represent a class holding a reference to another type. The choice is a modelling convention:
- If the related type is a primitive or simple data type (String, Integer, Date), model it as an attribute.
- If the related type is a class in your model (e.g., Student has a reference to Course), model it as an association line — this makes the relationship explicit and allows multiplicity to be shown.
An association line is preferred when the relationship itself carries meaning — such as role names or multiplicity constraints.
Navigability specifies which direction you can traverse the relationship in code. An arrowhead on one end means: the class at the tail end has a reference to the class at the arrow end — but not necessarily vice versa.
Example: Order → Customer
An Order object knows which Customer placed it. A Customer object does not hold a list
of their Orders (unless you add an arrow in the other direction).
Navigability decisions affect implementation: a unidirectional association means one class holds a reference field; a bidirectional association means both do (and both must be kept in sync, which adds complexity).
Read multiplicity as: "One instance of [class at this end] is associated with [multiplicity] instances of [class at the other end]."
Example: Student 0..* —————— 1..* Course
- One Course is taken by zero or more Students.
- One Student is enrolled in one or more Courses.
Always read from the perspective of one instance at your end, looking across to the multiplicity at the other end.
Multiplicity is not a description of typical behaviour — it is a constraint on valid
system state. If you specify 1..* students per course, then a course with
zero students is an invalid state.
This has implementation consequences:
- A
0..1relationship means the field can be null - A
1relationship means the field must always be set - A
1..*relationship means the collection must never be empty
Getting multiplicity right requires careful thought about the business rules the system must enforce.
Watch
Video coming soon
Check Your Understanding
Select the best answer for each question.
What does the multiplicity notation '0..*' mean?
In UML class notation, which visibility symbol denotes a private attribute?
Activities
Individual task
Review the shared use case diagram from Unit 3. Identify the main classes that will be needed to implement it.
For each class, produce a UML class box (on paper or in a tool) with:
- The class name (UpperCamelCase)
- At least two attributes with visibility and type
- At least one operation with a signature
Aim for at least four classes.
Pair task
Review your partner's class list against these questions:
- Are there any attributes that should be classes? For example, an attribute address : String might be better modelled as an Address class.
- Are there any obvious missing classes?
- Draw the associations between your combined set of classes. Which classes know about which others?
Group task
Combine your individual class diagrams into a single shared class diagram. Then:
- Add multiplicities to all associations.
- Check that every association multiplicity reflects a real business rule — not just a guess.
- Agree on attribute visibility: which attributes should be private? Which operations public?
Keep this diagram — you will extend it significantly in Unit 5.
Review
- Top — class name only (italics if abstract)
- Middle — attributes:
visibility name : type [= default] - Bottom — operations:
visibility name(params) : returnType
Each use case describes what a user can do; the class diagram describes the data and behaviour needed to support those use cases. Each noun in a use case description is a candidate class. Each action a use case requires maps to one or more operations.
There is no one-to-one mapping — design involves judgement. But a class diagram with no connection to the use cases is an early warning sign that the model is not grounded in actual requirements.
Proceed to Unit 5: Class Diagrams — Structure II when ready.