UML class diagram with 6 classes (Customer, VIP, Guest, Order, LineItem, Product), 1 interface (Billable). VIP extends Customer. Guest extends Customer. Order implements Billable. Customer is associated with Order with multiplicity one to many. Order composes LineItem with multiplicity one to one or more. LineItem is associated with Product with multiplicity many to one.
Billable — Attributes: none declared — Operations: public processPayment(): bool
Relationships
VIP extends Customer
Guest extends Customer
Order implements Billable
Customer is associated with Order with multiplicity one to many
Order composes LineItem with multiplicity one to one or more
LineItem is associated with Product with multiplicity many to one
Introduction
Pedagogical Note: This chapter is designed using principles of Active Engagement (frequent retrieval practice). We will build concepts incrementally. Please complete the “Quick Checks” without looking back at the text—this introduces a “desirable difficulty” that strengthens long-term memory.
🎯 Learning Objectives
By the end of this chapter, you will be able to:
Translate real-world object relationships into UML Class Diagrams.
Differentiate between structural relationships (Association, Aggregation, Composition).
Read and interpret system architecture from UML class diagrams.
Diagram – The Blueprint of Software
Imagine you are an architect designing a complex building. Before laying a single brick, you need blueprints. In software engineering, we use similar models. The Unified Modeling Language (UML) is the most common one.
Among UML diagrams, Class Diagrams are the most common ones, because they are very close to the code. They describe the static structure of a system by showing the system’s classes, their attributes, operations (methods), and the relationships among objects.
The Core Building Blocks
2.1 Classes
A Class is a template for creating objects. In UML, a class is represented by a rectangle divided into three compartments:
Top: The Class Name.
Middle: Attributes (variables/state).
Bottom: Operations (methods/behavior).
2.2 Modifiers (Visibility)
To enforce encapsulation, UML uses symbols to define who can access attributes and operations:
+Public: Accessible from anywhere.
-Private: Accessible only within the class.
#Protected: Accessible within the class and its subclasses.
~Package/Default: Accessible by any class in the same package.
Detailed description
UML class diagram with 1 class (User).
Classes
User — Attributes: private username: String; private email: String; protected id: int — Operations: public login(): boolean; public resetPassword(): void
2.3 Interfaces
An Interface represents a contract. It tells us what a class must do, but not how it does it. It is denoted by the <<interface>> stereotype. Interfaces contain method signatures and usually do not declare attributes (the UML specification allows it, but I recommend not to use it)
Detailed description
UML class diagram with 1 interface (Payable).
Interfaces
Payable — Attributes: none declared — Operations: public processPayment(): bool
Quick Check 1 (Retrieval Practice)Cover the screen above. What do the symbols +, -, and # stand for? Why does an interface lack an attributes compartment?
Connecting the Dots: Relationships
Software is never just one class working in isolation. Classes interact. We represent these interactions with different types of lines and arrows.
Generalization — “Is-A” Relationships
Generalization connects a subclass to a superclass. It means the subclass inherits attributes and behaviors from the parent.
UML Symbol: A solid line with a hollow, closed arrow pointing to the parent.
Interface Realization
When a class agrees to implement the methods defined in an interface, it “realizes” the interface.
UML Symbol: A dashed line with a hollow, closed arrow pointing to the interface.
Detailed description
UML class diagram with 3 classes (Car, Sedan, SUV), 1 interface (Vehicle). Car implements Vehicle. Sedan extends Car. SUV extends Car.
Classes
Car — Attributes: private make: String — Operations: public startEngine(): void
Sedan — Attributes: none declared — Operations: none declared
SUV — Attributes: none declared — Operations: none declared
Interfaces
Vehicle — Attributes: none declared — Operations: public startEngine(): void
Relationships
Car implements Vehicle
Sedan extends Car
SUV extends Car
Dependency (Weakest Relationship)
A dependency indicates that one class uses another, but does not hold a permanent reference to it. For example, a class might use another class as a method parameter, local variable, or return type. Dependency is the weakest relationship in a class diagram.
UML Symbol: A dashed line with an open arrowhead.
Detailed description
UML class diagram with 2 classes (Train, ButtonPressedEvent). Train depends on ButtonPressedEvent.
In this example, Train depends on ButtonPressedEvent because it uses it as a parameter type in addStop(). However, Train does not store a permanent reference to ButtonPressedEvent—the dependency exists only for the duration of the method call.
Here is another example where a class depends on an exception it throws:
Detailed description
UML class diagram with 2 classes (ChecksumValidator, InvalidChecksumException). ChecksumValidator depends on InvalidChecksumException.
Classes
ChecksumValidator — Attributes: none declared — Operations: public execute(): bool; public validate(): void
ChecksumValidator depends on InvalidChecksumException
Association — “Has-A” / “Knows-A” Relationships
A basic structural relationship indicating that objects of one class are connected to objects of another (e.g., a “Teacher” knows about a “Student”). Attributes can also be represented as association lines: a line is drawn between the owning class and the target attribute’s class, providing a quick visual indication of which classes are related.
UML Symbol: A simple solid line.
You can also name associations and make them directional using an arrowhead to indicate navigability (which class holds a reference to the other).
Detailed description
UML class diagram with 2 classes (Student, Course). Student is associated with Course with multiplicity many to one or more labeled "enrolled in".
Book — Attributes: none declared — Operations: none declared
Relationships
Author is associated with Book with multiplicity one to one or more labeled "writes"
Navigability
When neither end of an association is annotated with an arrowhead or X mark, navigability is formally undefined in UML 2.5. By convention, many authors and tools render this case as bidirectional (both classes know about each other), but you should not rely on the default — make navigability explicit when it matters. In practice, the relationship is often one-way: only one class holds a reference to the other. UML uses arrowheads and X marks to show this navigability.
Navigable end An open arrowhead pointing to the class that can be “reached”. The left object has a reference to the right object.
Non-Navigable end An X on the end that cannot be navigated. This explicitly states that the class at the X end does not hold a reference to the other.
Here are the four navigability combinations, each with an example:
Unidirectional (one arrowhead): Only one class holds a reference.
Detailed description
UML class diagram with 2 classes (Vote, Politician). Vote references Politician.
Boss — Attributes: none declared — Operations: none declared
Relationships
Employee and Boss reference each other
Employee knows about their Boss, and Boss knows about their Employee. Note that a plain line with no arrowheads on either end has unspecified navigability per UML 2.5 — not “bidirectional by default.” If you mean both directions are navigable, draw arrowheads on both ends (as above) to make that explicit.
Non-navigable on one end (X on one side): One class is explicitly prevented from navigating.
Detailed description
UML class diagram with 2 classes (Voter, Vote). Voter has a non-navigable association with Vote.
In the full UML notation, an X on the Voter end means that the opposite lifeline cannot navigate to it — i.e., Vote does not hold a reference back to Voter. (Voter’s navigability toward Vote is then determined by whatever is marked on the Vote end.) Note: the X mark is a formal UML 2 notation that many simplified tools do not render, and per UML 2.5, when one end carries a navigability arrow but the other end is unmarked, the unmarked end’s navigability is formally undefined, not “non-navigable” by default.
Non-navigable on both ends (X on both sides): Neither class holds a reference—the association is recorded only in the model, not in code.
Detailed description
UML class diagram with 2 classes (Account, ClearTextPassword). Account and ClearTextPassword have a non-navigable association.
Account and ClearTextPassword have a non-navigable association
An X on both ends of AccountClearTextPassword means neither class should store a reference to the other. This is a deliberate design decision (e.g., for security: an Account should never hold a reference to a ClearTextPassword).
When to use navigability: Navigability is a design-level detail. In analysis/domain models, plain associations (no arrowheads) are preferred because you haven’t decided which class holds the reference yet. Once you move into detailed design, add navigability to show which class stores the reference—this maps directly to code (a field/attribute in the class at the arrow tail).
Aggregation (“Owns-A”)
A specialized association where one class belongs to a collection, but the parts can exist independently of the whole. If a University closes down, the Professors still exist. Think of aggregation as a long-term, whole-part association.
UML Symbol: A solid line with an empty diamond at the “whole” end.
Detailed description
UML class diagram with 2 classes (University, Professor). University aggregates Professor with multiplicity one to many.
Classes
University — Attributes: none declared — Operations: none declared
Professor — Attributes: none declared — Operations: none declared
Relationships
University aggregates Professor with multiplicity one to many
Composition (“Is-Made-Up-Of”)
A strict relationship where the parts cannot exist without the whole. If you destroy a House, the Rooms inside it are also destroyed. A part may belong to only one composite at a time (exclusive ownership), and the composite has sole responsibility for the lifetime of its parts.
UML Symbol: A solid line with a filled diamond at the “whole” end.
Per the UML spec, the multiplicity on the composite end must be 1 or 0..1.
Detailed description
UML class diagram with 2 classes (House, Room). House composes Room with multiplicity one to one or more.
Classes
House — Attributes: none declared — Operations: none declared
House composes Room with multiplicity one to one or more
A helpful way to think about the difference: In C++, aggregation is usually expressed through pointers/references (the part can exist separately), while composition is expressed by containing instances by value (the part’s lifetime is tied to the whole). In Java and Python, every object reference is effectively a pointer — the distinction between aggregation and composition is communicated through design intent (who created the part? who destroys it?) rather than through language syntax. Inner classes in Java are one indicator of composition but are not required.
⚠ Honest caveat on aggregation. Aggregation has intentionally informal semantics in the UML 2 specification. Martin Fowler (UML Distilled) observes: “Aggregation is strictly meaningless; as a result, I recommend that you ignore it in your own diagrams.” When you aren’t sure whether something is aggregation or plain association, use association — it is always safe. Reserve the hollow diamond for the cases where part-whole semantics clearly add communicative value.
Quick Check 2 (Self-Explanation)In your own words, explain the difference between the empty diamond (Aggregation) and the filled diamond (Composition). Give a real-world example of each that is not mentioned in this text.
Relationship Strength Summary
From weakest to strongest, the class relationships are:
Relationship
Symbol
Meaning
Example
Dependency
Dashed arrow
"uses" temporarily
Method parameter, thrown exception
Association
Solid line
"knows about" structurally
Employee knows about Boss
Aggregation
Hollow diamond
"has-a" (parts can exist alone)
Library has Books
Composition
Filled diamond
"made up of" (parts die with whole)
House is made of Rooms
Generalization
Hollow triangle
"is-a" (inheritance)
Car is-a Vehicle
Realization
Dashed hollow triangle
"implements" (interface)
Car implements Drivable
⚠ The Five Most Common UML Class Diagram Mistakes
Empirical studies of student diagrams (Chren et al., “Mistakes in UML Diagrams: Analysis of Student Projects in a Software Engineering Course”, ICSE SEET 2019) identify these recurring errors. Watch for them in your own work:
#
Mistake
Fix
1
Generalization arrow pointed the wrong way — triangle at the child instead of the parent
The triangle always rests at the parent. Sanity-check with the “is-a” sentence: “A [child] is a [parent]”.
2
Multiplicity on the wrong end — e.g., * placed next to the “one” side
Multiplicity answers “for one of the opposite class, how many of this class?” Place it next to the class being quantified.
3
Missing multiplicity on one end
Per Ambler (G117), always show multiplicity on both ends of every relationship. An unlabeled end is ambiguous, not “just 1.”
4
Confusing aggregation and composition — using the filled diamond when parts are actually shared
Composition = exclusive ownership and lifecycle dependency. If the part can exist without the whole, use aggregation (or plain association).
5
Verbose 0..* when * suffices
Use the shorthand * for zero-or-more. The UML spec defines them as identical; * is more concise. Reserve 0..* only when contrasting explicitly with 1..* nearby.
Pedagogy tip: Before turning in any class diagram, run this five-item checklist over every relationship. Catching these five mistakes catches the majority of grading-level errors.
Advanced Class Notation
Abstract Classes and Operations
An abstract class is a class that cannot be instantiated directly—it serves as a base for subclasses. In UML, an abstract class is indicated by italicizing the class name or adding {abstract}.
An abstract operation is a method with no implementation, intended to be supplied by descendant classes. Abstract operations are shown by italicizing the operation name.
Detailed description
UML class diagram with 1 class (Rectangle), 1 abstract class (Shape). Rectangle extends Shape.
Classes
Rectangle — Attributes: private width: int; private length: int — Operations: public setWidth(width: int): void; public setHeight(height: int): void; public draw(): void
Abstract classes
Shape — Attributes: private color: int — Operations: public setColor(r: int, g: int, b: int): void; + draw(): void (abstract)
Relationships
Rectangle extends Shape
In this example, Shape is abstract (it cannot be created directly) and declares an abstract draw() method. Rectangle inherits from Shape and provides a concrete implementation of draw().
Static Members
Static (class-level) attributes and operations belong to the class itself rather than to individual instances. In UML, static members are shown underlined.
Detailed description
UML class diagram with 1 class (MathUtils).
Classes
MathUtils — Attributes: +PI: double (static) — Operations: +abs(n: int): int (static); public round(n: double): int
From Code to Diagram: Worked Examples
A key skill is translating between code and UML class diagrams. Let’s work through several examples that progressively build this skill.
UML class diagram with 1 class (BaseSynchronizer).
Classes
BaseSynchronizer — Attributes: none declared — Operations: public synchronizationStarted(): void
Each public method becomes a + operation in the bottom compartment. The return type follows a colon after the method signature.
Example 2: Attributes and Associations
When a class holds a reference to another class, you can show it either as an attribute or as an association line (but be consistent throughout your diagram).
Notice: in the Java version, the roster field has package visibility (~) because no access modifier was specified (Java default is package-private). Other languages express visibility differently, but the relationship is the same: Student holds a reference to a Roster.
ChecksumValidator depends on InvalidChecksumException
The ChecksumValidatordepends onInvalidChecksumException (it uses it in a throws clause and catch block) but does not store a permanent reference to it. This is a dependency, not an association.
UML class diagram with 2 classes (Division, Employee). Division aggregates Employee with multiplicity one to many. Division is associated with Employee with multiplicity one to 10.
Division aggregates Employee with multiplicity one to many
Division is associated with Employee with multiplicity one to 10
The List<Employee> field suggests aggregation (the collection can grow dynamically, employees can exist independently). The array with a fixed size of 10 is a direct association with a specific multiplicity.
Putting It All Together: The E-Commerce System
Pedagogical Note: We are now combining isolated concepts into a complex schema. This reflects how you will encounter UML in the real world.
Let’s read the architectural blueprint for a simplified E-Commerce system.
Detailed description
UML class diagram with 6 classes (Customer, VIP, Guest, Order, LineItem, Product), 1 interface (Billable). VIP extends Customer. Guest extends Customer. Order implements Billable. Customer is associated with Order with multiplicity one to many. Order composes LineItem with multiplicity one to one or more. LineItem is associated with Product with multiplicity many to one.
Billable — Attributes: none declared — Operations: public processPayment(): bool
Relationships
VIP extends Customer
Guest extends Customer
Order implements Billable
Customer is associated with Order with multiplicity one to many
Order composes LineItem with multiplicity one to one or more
LineItem is associated with Product with multiplicity many to one
System Walkthrough:
Generalization:VIP and Guest are specific types of Customer.
Association (Multiplicity):1 Customer can have * (zero to many) Orders.
Interface Realization:Order implements the Billable interface.
Composition: An Order strongly contains 1..* (one or more) LineItems. If the order is deleted, the line items are deleted.
Association: Each LineItem points to exactly 1Product.
Real-World Examples
The following examples apply everything from this chapter to systems you interact with every day. Try reading each diagram yourself before the walkthrough — this is retrieval practice in action.
Example 1: Spotify — Music Streaming Domain Model
Scenario: An analysis-level domain model for a music streaming service. The goal is to capture what things are and how they relate — not implementation details like database schemas or network calls.
Detailed description
UML class diagram with 6 classes (User, FreeUser, PremiumUser, Playlist, Track, Artist). FreeUser extends User. PremiumUser extends User. User composes Playlist with multiplicity one to many labeled "owns". Playlist aggregates Track with multiplicity many to many labeled "contains". Track is associated with Artist with multiplicity many to one or more labeled "performedBy".
Classes
User — Attributes: none declared — Operations: public search(query: String): list; public createPlaylist(name: String): Playlist
Track — Attributes: public title: String; public duration: int — Operations: none declared
Artist — Attributes: public name: String — Operations: none declared
Relationships
FreeUser extends User
PremiumUser extends User
User composes Playlist with multiplicity one to many labeled "owns"
Playlist aggregates Track with multiplicity many to many labeled "contains"
Track is associated with Artist with multiplicity many to one or more labeled "performedBy"
What the UML notation captures:
Generalization (hollow triangle):FreeUser and PremiumUser both extend User, inheriting search() and createPlaylist(). Only PremiumUser adds download() — a capability unlocked by upgrading. The hollow triangle always points up toward the parent class.
Composition (filled diamond, User → Playlist): A Userowns their playlists. Deleting a user account deletes their playlists — the parts cannot outlive the whole. The filled diamond sits on the owner’s side.
Aggregation (hollow diamond, Playlist → Track): A Playlistcontains tracks, but tracks exist independently — the same track can appear in many playlists. Deleting a playlist does not remove the track from the catalog.
Association with multiplicity (Track → Artist): Each track is performed by 1..* artists — at least one (solo) or more (collaboration). This multiplicity directly encodes a real business rule.
Analysis vs. design level: This diagram has no visibility modifiers (+, -). That is intentional — at the analysis level we model what things are and do, not encapsulation decisions. Visibility is a design-level concern added in a later phase.
Example 2: GitHub — Pull Request Design Model
Scenario: A design-level diagram (note the visibility modifiers) showing how GitHub’s code review system could be modeled internally. Notice how an interface creates a formal contract between components.
Detailed description
UML class diagram with 4 classes (Repository, PullRequest, Review, CICheck), 1 interface (Mergeable). PullRequest implements Mergeable. Repository composes PullRequest with multiplicity one to many. PullRequest composes Review with multiplicity one to many. PullRequest depends on CICheck.
Mergeable — Attributes: none declared — Operations: public canMerge(): bool; public merge(): void
Relationships
PullRequest implements Mergeable
Repository composes PullRequest with multiplicity one to many
PullRequest composes Review with multiplicity one to many
PullRequest depends on CICheck
What the UML notation captures:
Interface Realization (dashed hollow arrow):PullRequest implements Mergeable — a contract committing the class to provide canMerge() and merge(). A merge pipeline can work with any Mergeable object without knowing the concrete type.
Composition (Repository → PullRequest): A PR cannot exist without its repository. Delete the repo, and all its PRs are deleted — the filled diamond on Repository’s side shows ownership.
Composition (PullRequest → Review): A review only exists in the context of one PR. 1 *-- * reads: one PR can have zero or more reviews; each review belongs to exactly one PR.
Dependency (dashed open arrow, PullRequest → CICheck):PullRequestusesCICheck temporarily — perhaps receiving it as a method parameter. It does not hold a permanent field reference, so this is a dependency, not an association.
Example 3: Uber Eats — Food Delivery Domain Model
Scenario: The domain model for a food delivery platform. This example is excellent for practicing multiplicity — every 0..1, 1, and * encodes a real business rule the engineering team must enforce.
Detailed description
UML class diagram with 6 classes (Customer, Order, OrderItem, MenuItem, Restaurant, Driver). Customer is associated with Order with multiplicity one to many labeled "places". Order composes OrderItem with multiplicity one to one or more labeled "contains". OrderItem is associated with MenuItem with multiplicity many to one labeled "references". Restaurant is associated with MenuItem with multiplicity one to one or more labeled "offers". Driver is associated with Order with multiplicity zero or one to zero or one labeled "delivers".
Customer is associated with Order with multiplicity one to many labeled "places"
Order composes OrderItem with multiplicity one to one or more labeled "contains"
OrderItem is associated with MenuItem with multiplicity many to one labeled "references"
Restaurant is associated with MenuItem with multiplicity one to one or more labeled "offers"
Driver is associated with Order with multiplicity zero or one to zero or one labeled "delivers"
What the UML notation captures:
Customer "1" -- "*" Order: One customer can have zero orders (a new account) or many. The navigability arrow shows Customer holds the reference — in code, a Customer would have an orders collection field.
Composition (Order → OrderItem): Order items only exist within an order. Cancelling the order destroys the items. The 1..* on OrderItem enforces that every order must have at least one item.
OrderItem "*" -- "1" MenuItem: Each item references exactly one menu item. Many orders can reference the same menu item — deleting an order does not remove the menu item from the restaurant’s catalog.
Driver "0..1" -- "0..1" Order: A driver handles at most one active delivery at a time; an order has at most one assigned driver. Before dispatch, both sides satisfy 0 — neither requires the other to exist yet. This captures a real business constraint in two characters.
Example 4: Netflix — Content Catalogue Model
Scenario: Netflix serves two fundamentally different types of content — movies (watched once) and TV shows (composed of seasons and episodes). This diagram shows how inheritance and composition work together to model a content catalog.
Detailed description
UML class diagram with 4 classes (Movie, Season, Episode, Genre), 2 abstract classes (Content, TVShow). Movie extends Content. TVShow extends Content. TVShow composes Season with multiplicity one to one or more labeled "contains". Season composes Episode with multiplicity one to one or more labeled "contains". Content is associated with Genre with multiplicity many to one or more labeled "classifiedBy".
Classes
Movie — Attributes: private duration: int — Operations: public play(): void
Season — Attributes: private seasonNumber: int — Operations: none declared
Episode — Attributes: private episodeNumber: int; private duration: int — Operations: public play(): void
TVShow composes Season with multiplicity one to one or more labeled "contains"
Season composes Episode with multiplicity one to one or more labeled "contains"
Content is associated with Genre with multiplicity many to one or more labeled "classifiedBy"
What the UML notation captures:
Abstract class (abstract class Content): The italicised class name and {abstract} on play() signal that Content is never instantiated directly — you never watch a “content”, only a Movie or an Episode. Movie overrides play() with its own implementation. TVShow is also abstract (it inherits play() without overriding it) — you don’t play a show as a whole, you play one of its Episodes, which provides its own concrete play().
Generalization hierarchy: Both Movie and TVShow extend Content, inheriting title and rating. A Movie adds duration directly; a TVShow delegates duration implicitly through its episodes.
Nested composition (TVShow → Season → Episode): A TVShow is composed of seasons; each season is composed of episodes. Delete a show and the seasons disappear; delete a season and the episodes disappear. The chain of filled diamonds models this cascade.
Association with multiplicity (Content → Genre): A movie or show belongs to 1..* genres (at least one — e.g., Action). A genre classifies * content items. This is a plain association — deleting a genre does not delete the content.
Example 5: Strategy Pattern — Pluggable Payment Processing
Scenario: A shopping cart needs to support multiple payment methods (credit card, PayPal, crypto) and let users switch between them at runtime. This is the Strategy design pattern — and a class diagram is the canonical way to document it.
Interface as contract:PaymentStrategy defines the contract — pay() and refund(). Every concrete implementation must provide both. The interface appears at the top of the hierarchy, with implementors below.
**Three realizations (..
>):** CreditCardPayment, PayPalPayment, and CryptoPayment all implement PaymentStrategy. The dashed hollow arrow points toward the interface each class promises to fulfill.
Association ShoppingCart --> PaymentStrategy: The cart holds a reference to PaymentStrategy — not to any specific implementation. This navigability arrow (open head, not filled diamond) means ShoppingCart has a field of type PaymentStrategy. Crucially, it is typed to the interface, not a concrete class.
The power of this design: Because ShoppingCart depends on PaymentStrategy (the interface), you can call cart.setPayment(new CryptoPayment()) at runtime and the cart works without any changes to its own code. The class diagram makes this extensibility visible — and it shows exactly where the seam between context and strategy is.
Connection to practice: This is the same pattern behind Java’s Comparator, Python’s sort(key=...), and every payment SDK you will ever integrate in your career. Class diagrams let you see the shape of the pattern independent of any language.
5. Chapter Review & Spaced Practice
To lock this information into your long-term memory, do not skip this section!
Active Recall Challenge:
Grab a blank piece of paper. Without looking at this chapter, try to draw the UML Class Diagram for the following scenario:
A School is composed of one or many Departments (If the school is destroyed, departments are destroyed).
A Department aggregates many Teachers (Teachers can exist without the department).
Teacher is a subclass of an Employee class.
The Employee class has a private attribute salary and a public method getDetails().
Review your drawing against the rules in sections 2 and 3. How did you do? Identifying your own gaps in knowledge is the most powerful step in the learning process!
6. Practice
Test your knowledge with these retrieval practice exercises. These diagrams are rendered dynamically to ensure you can recognize UML notation in any context.
UML Class Diagram Flashcards
Quick review of UML Class Diagram notation and relationships.
Difficulty:Basic
What does the following symbol represent in a class diagram?
Detailed description
UML class diagram with 2 classes (Department, Professor). Department aggregates Professor.
Classes
Department — Attributes: none declared — Operations: none declared
Professor — Attributes: none declared — Operations: none declared
Relationships
Department aggregates Professor
Aggregation
A hollow diamond on the parent class indicates Aggregation, representing a ‘part-of’ relationship where the parts can exist independently of the whole.
Difficulty:Advanced
How do you denote a Static Method in UML Class Diagrams?
By underlining the method name.
Static (class-level) members are underlined in UML.
Detailed description
UML class diagram with 1 class (MathUtils).
Classes
MathUtils — Attributes: none declared — Operations: +abs(n: int) : int (static); public pi() : double
Difficulty:Intermediate
What is the difference between these two relationships?
Detailed description
UML class diagram with 4 classes (Building, Room, Library, Book). Building composes Room. Library aggregates Book.
Classes
Building — Attributes: none declared — Operations: none declared
Book — Attributes: none declared — Operations: none declared
Relationships
Building composes Room
Library aggregates Book
The first is Composition (strong), the second is Aggregation (weak).
A filled diamond () is Composition, meaning the parts cannot exist without the whole. A hollow diamond () is Aggregation.
Difficulty:Intermediate
What is the difference between Generalization and Realization arrows?
Generalization = solid line with hollow arrowhead. Realization = dashed line with hollow arrowhead.
Both use the same hollow triangle arrowhead, so the line style is the only tell: solid means inheriting from a superclass, dashed means implementing an interface.
Detailed description
UML class diagram with 2 classes (Bird, Sparrow), 1 interface (Flyable). Bird implements Flyable. Sparrow extends Bird.
Classes
Bird — Attributes: none declared — Operations: public fly(): void
Flyable — Attributes: none declared — Operations: public fly(): void
Relationships
Bird implements Flyable
Sparrow extends Bird
Difficulty:Basic
What do the four visibility symbols mean in UML?
+ public, - private, # protected, ~ package.
These symbols appear before attribute and operation names in design-level class diagrams. They should not be shown on analysis/domain models.
Detailed description
UML class diagram with 1 class (Example).
Classes
Example — Attributes: public publicAttr: String; private privateAttr: int; protected protectedAttr: bool; package packageAttr: float — Operations: none declared
Difficulty:Basic
What does the multiplicity 1..* mean on an association?
One or more — at least one instance is required.
Common multiplicities: 1 (exactly one), 0..1 (zero or one), 0..* (zero or more), 1..* (one or more). Always show multiplicity on both ends of an association.
Difficulty:Intermediate
What relationship is represented in the diagram below, and when is it used?
Detailed description
UML class diagram with 2 classes (Train, Event). Train depends on Event.
A Dependency — the weakest relationship. One class temporarily uses another.
A dashed arrow with an open arrowhead () denotes a Dependency. It means a class uses another as a method parameter, local variable, return type, or thrown exception — but does not hold a permanent reference. It is the weakest of all class relationships.
Difficulty:Advanced
How do you indicate an abstract class in UML?
By italicizing the class name, or adding {abstract}.
An abstract class cannot be instantiated directly. Abstract operations (methods with no implementation) are also shown in italics. Subclasses must provide concrete implementations.
Detailed description
UML class diagram with 1 class (Circle), 1 abstract class (Shape). Circle extends Shape.
Classes
Circle — Attributes: none declared — Operations: public draw(): void
List the class relationships from weakest to strongest.
Dependency < Association < Aggregation < Composition < Generalization/Realization
Dependency (dashed arrow, temporary use) is weakest. Association (solid line, structural link) is stronger. Aggregation (hollow diamond, parts can exist alone) and Composition (filled diamond, parts die with whole) add ownership semantics. Generalization (hollow triangle, inheritance) and Realization (dashed hollow triangle, interface implementation) represent the strongest “is-a” relationships.
Difficulty:Advanced
What does a navigable association () indicate?
The class at the tail holds a reference to the class at the arrowhead. Only one direction is navigable.
A plain association () has unspecified navigability per UML 2.5 — not “bidirectional by default.” An arrowhead makes it unidirectional: in code, the tail class has a field of the head class’s type. This is a design-level detail — omit it in early domain models.
Detailed description
UML class diagram with 2 classes (Employee, Boss). Employee references Boss.
Order — Attributes: private id: int; private date: Date — Operations: none declared
The multiplicity near Order tells how many orders one customer can be linked to. It does not mean one order has many customers.
Composition would use a filled diamond and would imply lifecycle ownership. This diagram shows a directed association, not part-whole ownership.
Generalization uses a hollow triangle arrowhead. A plain directed association does not mean Order inherits from Customer.
Correct Answer:
Explanation
This is a directed association from Customer to Order. The multiplicity 1 on the Customer end and * on the Order end means one customer can be associated with any number of orders.
Difficulty:Intermediate
Which of the following members are private in the class Engine?
Detailed description
UML class diagram with 1 class (Engine).
Classes
Engine — Attributes: private serialNumber: String; protected type: String; public horsepower: int; private isRunning: boolean; package id: int — Operations: public start(); private resetInternal()
serialNumber has the - visibility marker, so it is private. Omitting it usually means reading names instead of the UML visibility symbols.
# means protected, not private. Protected members are visible to the class and its subclasses.
+ means public. Public members are not private even when they are fields.
isRunning has the - marker, so it is private. The same visibility notation applies to fields and methods.
~ means package/internal visibility in UML notation. It is not the same as private.
resetInternal() has the - marker, so the method is private. Parentheses do not change the visibility rule.
Correct Answers:
Explanation
The - prefix marks private members, so serialNumber, isRunning, and resetInternal() are the private ones. In UML, - denotes private, + public, # protected, and ~ package/internal. The visibility symbol applies the same way to fields and methods.
Difficulty:Basic
What type of relationship is shown here between Graphic and Circle?
Detailed description
UML class diagram with 1 class (Circle), 1 abstract class (Graphic). Circle extends Graphic.
Classes
Circle — Attributes: none declared — Operations: public draw()
Aggregation would use a hollow diamond and express a whole-part relationship. The hollow triangle means inheritance.
Realization uses a dashed line with a hollow triangle and is used for implementing an interface. Graphic is shown as an abstract class, and the line is solid.
Dependency uses a dashed arrow and means temporary use. The solid hollow-triangle arrow points to the superclass.
Correct Answer:
Explanation
This is Generalization (Inheritance) — the hollow triangle points to the parent. Circle inherits from Graphic, which is an abstract class providing the draw() contract that Circle implements concretely.
Difficulty:Basic
Which of the following relationships is shown here?
Detailed description
UML class diagram with 2 classes (Car, Engine). Car composes Engine.
Classes
Car — Attributes: none declared — Operations: none declared
A plain association would be drawn without a filled diamond. The filled diamond adds strong whole-part ownership semantics.
Aggregation uses a hollow diamond. A filled diamond is the composition notation.
Inheritance uses a hollow triangle arrowhead. The diamond notation is about ownership, not subclassing.
Correct Answer:
Explanation
The filled diamond represents Composition, indicating that, in this model, Engine’s lifecycle is tied to Car. The filled diamond () represents Composition — strong ownership where the part’s lifecycle is controlled by the whole.
Difficulty:Intermediate
What type of relationship is shown between Payment and Processable?
Detailed description
UML class diagram with 1 class (Payment), 1 interface (Processable). Payment implements Processable.
Processable — Attributes: none declared — Operations: public process(): bool
Relationships
Payment implements Processable
Generalization would be a solid line with a hollow triangle. The dashed hollow-triangle line marks realization of an interface.
Association is a structural link between instances. Here the notation says Payment fulfills the Processable interface contract.
A dependency is a dashed arrow with an open arrowhead, not a hollow triangle. Realization is stronger: it means implementation of the interface.
Correct Answer:
Explanation
This is Realization — the dashed line with a hollow arrowhead () shows Payment commits to implementing every method in the Processable interface. Generalization (inheritance) uses a solid line with the same hollow arrowhead instead — the dashed-vs-solid line is what distinguishes the two.
Difficulty:Intermediate
What does the multiplicity 0..* on the Order side mean in this diagram?
Detailed description
UML class diagram with 2 classes (Customer, Order).
Order — Attributes: private date: Date — Operations: none declared
0..* explicitly allows zero. A minimum of one would be written 1..*.
The multiplicity shown on the Order end is read as how many orders one customer may be associated with. It is not the multiplicity of customers per order.
0..* is still a constraint: the lower bound is zero and the upper bound is unbounded. It is not the same as leaving multiplicity unspecified.
Correct Answer:
Explanation
0..* means zero or more — a Customer can have any number of Orders, including none. Reading the multiplicity on the Order end answers “for one Customer, how many Orders?” — here, anywhere from none to unbounded.
Difficulty:Advanced
Looking at this e-commerce diagram, which statements are correct? (Select all that apply.)
Detailed description
UML class diagram with 3 classes (Order, LineItem, Product), 1 interface (Billable). Order implements Billable.
Classes
Order — Attributes: private status: String — Operations: public calcTotal(): float
LineItem — Attributes: private quantity: int — Operations: none declared
Billable — Attributes: none declared — Operations: public processPayment(): bool
Relationships
Order implements Billable
The filled diamond at Order indicates composition: LineItem is part of the order’s lifecycle. Omitting this misses the ownership meaning of the diamond.
Composition says the part’s lifecycle is tied to the whole in this model. A LineItem is not modeled as independently existing without its Order.
The dashed hollow-triangle arrow to Billable is realization. That means Order implements the interface.
The 1 multiplicity at the Product end means each LineItem is associated with exactly one product. Omitting this loses a business rule encoded in the diagram.
The Product relationship is a plain association with 0..* line items. A product may be referenced by zero line items and still exist.
Correct Answers:
Explanation
Composition destroys LineItems with their Order; Order realizes Billable; each LineItem references exactly one Product; and Products survive independently. The LineItem–Product link is a plain association (no diamond), which is why deleting an order leaves the Product in the catalog — only the composition diamond ties lifecycles together.
Public visibility is marked with +. The # symbol is protected.
Private visibility is marked with -. The # symbol allows subclass access in the UML visibility convention.
Package visibility is marked with ~. It is distinct from protected visibility.
Correct Answer:
Explanation
# means protected — accessible within the class and its subclasses, but not from unrelated classes. The full visibility set: + (public), - (private), # (protected), ~ (package).
Difficulty:Intermediate
What type of relationship is shown here between Formatter and IOException?
Detailed description
UML class diagram with 2 classes (Formatter, IOException). Formatter depends on IOException.
Association would imply a structural reference, usually drawn with a solid line. The dashed arrow means temporary use.
Composition would use a filled diamond and whole-part ownership. An exception type is not shown as part of Formatter.
Generalization uses a solid hollow-triangle arrowhead. Throwing or mentioning an exception type is a dependency, not inheritance.
Correct Answer:
Explanation
This is a Dependency () — the weakest class relationship. The dashed arrow shows Formatter temporarily uses IOException (e.g., throwing it) without storing a permanent reference.
Difficulty:Advanced
Given this Java code, what is the correct UML class diagram?
java public class Student {
Roster roster;
public void storeRoster(Roster r) {
roster = r;
}
}
A dependency would fit a parameter or local variable used temporarily. Here Roster roster; stores a field, so the relationship is structural.
A field alone does not prove composition. Composition would require whole-part lifecycle ownership, not just a stored reference assigned from outside.
There is no extends Roster relationship in the code. Storing a Roster field is not inheritance.
Correct Answer:
Explanation
This is an association with ~ (package) visibility. Storing Roster as a field is a permanent structural link (association, not dependency), and the missing Java access modifier defaults to package-private, which maps to ~ in UML.
Difficulty:Advanced
How is an abstract class indicated in UML?
Underlining is used in UML for static features, not abstract classes. Abstract classifiers are shown with italics or {abstract}.
<<interface>> marks an interface. An abstract class is still a class and can be marked abstract without becoming an interface.
# is protected visibility for members. It does not mark a class as abstract.
Correct Answer:
Explanation
An abstract class is shown by italicizing the class name or adding {abstract} — not by using <<interface>>, which is reserved for interfaces. Abstract operations (methods without an implementation) are italicized the same way.
Detailed description
UML class diagram with 1 class (Car), 1 abstract class (Vehicle). Car extends Vehicle.
Classes
Car — Attributes: none declared — Operations: public move(): void
Which of the following Java code patterns would result in a dependency (dashed arrow) relationship in UML, rather than an association? (Select all that apply.)
Detailed description
UML class diagram with 3 classes (ReportGenerator, Logger, IOException). ReportGenerator depends on Logger. ReportGenerator depends on IOException.
A parameter type is temporary use in the operation signature, so it is a dependency rather than a stored structural relationship.
A field stores a longer-lived reference. That is modeled as an association, aggregation, or composition depending on ownership, not a mere dependency.
Catching another type is temporary use inside behavior. That is a dependency, since no permanent reference is stored.
A local variable exists only inside a method call. UML models that kind of use as a dependency.
Correct Answers:
Explanation
A dependency arises from temporary usage — a parameter, local variable, return type, or caught exception. Storing a reference as an instance field instead creates a permanent structural link, which is an association (or aggregation/composition), not a dependency.
Difficulty:Advanced
What does the arrowhead on this association mean?
Detailed description
UML class diagram with 2 classes (Employee, Boss). Employee references Boss.
Boss — Attributes: none declared — Operations: none declared
Relationships
Employee references Boss
Inheritance would use a hollow triangle arrowhead. This open arrowhead on a solid association means navigability.
The arrow is read from tail to head: Employee can navigate to Boss. It does not show Boss holding the reference back.
A dependency would be dashed. This solid association means a structural link, commonly a field or reference.
Correct Answer:
Explanation
The open arrowhead () indicates navigability — the tail class (Employee) can reach the head class (Boss), but not necessarily the reverse. In code, this means Employee holds a field of type Boss. The notation differs from generalization (hollow triangle) and dependency (dashed arrow).
Difficulty:Advanced
When should you add navigability arrowheads to associations in a class diagram?
Detailed description
UML class diagram with 2 classes (Invoice, Customer). Invoice references Customer labeled "billedTo".
Early domain diagrams often leave navigability undecided. Adding arrowheads everywhere too soon can imply design decisions the team has not made.
This reverses the usual guidance. Analysis models often avoid navigability; design models add it when deciding which class stores references.
Navigability is part of UML association notation. It is optional, but it is real and useful at design level.
Correct Answer:
Explanation
Add navigability arrowheads at the design level to show which class holds the reference. Early analysis models prefer plain associations because the reference-holder hasn’t been decided yet; in detailed design the arrowhead maps directly to a field in the tail class.
Workout Complete!
Your Score: 0/14
Pedagogical Tip: If you find these challenging, it’s a good sign! Effortful retrieval is exactly what builds durable mental models. Try coming back to these tomorrow to benefit from spacing and interleaving.
7. Interactive Tutorials
Master UML class diagrams by writing code that matches target diagrams in our interactive tutorials:
Cookie & Privacy Notice:
This site stores a few preferences and your progress locally in your browser
(cookies and localStorage) so it works the way you left it.
Nothing is sent to or stored on any external server, and this site does not
sell, share, or disclose any user data to third parties.
View & manage your data →