UML: Class & Object Diagrams

Interfaces & Abstract Classes in UML

18 min Lesson 7 of 10

Interfaces & Abstract Classes in UML

Real-world systems rarely consist of a flat list of concrete classes. Most production domains contain types that define a contract — a set of operations every conforming class must implement — without providing the implementation themselves. UML models these with two closely related constructs: interfaces and abstract classes. Knowing when and how to use each is one of the most important modeling skills you can develop.

What Is an Interface?

An interface is a named collection of operation signatures with no attribute state and no implementation body. It declares what a class can do, not how it does it. Any class that provides implementations for all the operations in an interface is said to realize that interface.

Think of an interface as a formal promise. In a clinic booking system, you might define a Notifiable interface that promises the operation sendNotification(message : String) : void. Both Patient and Doctor can realize that interface independently, each sending notifications in their own way — SMS for patients, email for doctors — but the rest of the system only needs to know that any Notifiable object can be notified.

Notation: The Lollipop and the Dashed-Arrow

UML offers two equivalent notations for interfaces and realizations:

  1. Expanded notation — the interface is drawn as a class box with the stereotype «interface» above the name. A dashed arrow with a hollow triangle head (called a realization arrow) points from the implementing class to the interface.
  2. Lollipop notation (socket/ball) — a small circle (the "lollipop" or "ball") attached to the providing class by a short line. The circle is labeled with the interface name. A class that requires the interface is shown with a half-circle socket aimed at the ball. This compact notation is especially popular in component diagrams but is valid on class diagrams too.
Which notation should you use? Use the expanded (dashed-arrow) notation when you want to show the interface operations explicitly — this is the right choice for analysis documents where the audience needs to understand the contract. Use the lollipop when diagram space is tight and the audience already knows the interface contents, typically in architectural or component-level views.
Interface realization: expanded and lollipop notation «interface» Notifiable + sendNotification(msg : String) + getContactInfo() : String Patient - phone : String + sendNotification() Doctor - email : String + sendNotification() Expanded Notation Lollipop Notation AppointmentService + book() : Appointment + cancel(id : Integer) : void Schedulable ReminderEngine - interval : Integer + run() : void
Left: expanded realization notation — dashed arrow with hollow triangle pointing to the interface. Right: lollipop (ball-and-socket) notation for the same concept.

What Is an Abstract Class?

An abstract class sits between an interface and a concrete class. Like an interface it cannot be instantiated directly, but unlike an interface it can carry attribute state and provide partial implementations for some of its operations. Other operations are declared but left unimplemented — they are called abstract operations. Any concrete subclass must implement all inherited abstract operations.

In a library system, you might have an abstract class LibraryItem that defines the attributes itemId, title, and isAvailable — shared by all items — and an abstract operation checkout(memberId : Integer) : Boolean whose exact logic differs between a PhysicalBook and a DigitalEbook.

Notation: Italicized Names

UML marks abstract constructs with italics. The rules are simple:

  • An abstract class name is written in italic in the name compartment.
  • An abstract operation is written in italic in the operations compartment.
  • Concrete (non-abstract) operations in the same class remain upright (non-italic).
  • Alternatively, you may use the textual stereotype {abstract} after the class name, especially in tools that cannot render italic text.
Abstract class LibraryItem with concrete subclasses and interface Searchable LibraryItem # itemId : Integer # title : String # isAvailable : Boolean + getDetails() : String + checkout(memberId : Integer) italic = abstract op italic name = abstract class PhysicalBook - shelfLocation : String + checkout(memberId : Int) + reserve() : Boolean DigitalEbook - downloadUrl : String + checkout(memberId : Int) + streamOnline() : URL Searchable
Abstract class LibraryItem (italic name, italic abstract operation). PhysicalBook and DigitalEbook inherit and provide concrete implementations. The lollipop shows LibraryItem also realizes the Searchable interface.

Interface vs. Abstract Class: When to Use Which

A helpful way to decide is to ask two questions:

  • Do the conforming classes share state (attributes)? If yes, lean toward an abstract class so the shared attributes are defined once and inherited.
  • Can a class belong to multiple contracts simultaneously? A class can realize many interfaces but can only extend one abstract class (in most languages and in standard UML modeling practice). If you need multiple-contract flexibility, prefer interfaces.

In an online store, DigitalProduct might extend the abstract class Product (to inherit price and stockLevel) while simultaneously realizing the interfaces Downloadable and Licensable. That combination — one abstract superclass plus multiple interfaces — is the most common pattern in enterprise domain models.

Analyst shortcut: At the analysis stage, you rarely need to decide between interface and abstract class with full precision. It is perfectly valid to mark a class {abstract} and note which operations are abstract, then let the design team finalize whether it becomes a true abstract class or gets split into an interface and a partial implementation. What matters at analysis time is identifying the contract — the set of behaviors every conforming type must support.

Reading a Realization Arrow vs. a Generalization Arrow

Students often confuse these two arrows. Here is the rule:

  • Generalization (inheritance) — solid line with hollow triangle. Read as "is a". A PhysicalBook is a LibraryItem.
  • Realization (interface implementation)dashed line with hollow triangle. Read as "behaves as a" or "implements". A LibraryItem behaves as a Searchable.
Common mistake: Drawing a solid-line generalization arrow from a class to an interface is incorrect. An interface is not a superclass — it is a contract. Always use a dashed realization arrow (or the lollipop) when connecting a class to an interface.

Summary

Interfaces declare a contract using the «interface» stereotype and are connected to implementing classes via a dashed hollow-triangle realization arrow or the compact lollipop notation. Abstract classes are marked with italic names in the class box; abstract operations within them are also italic. Use interfaces when you need multiple-contract flexibility; use abstract classes when shared state or partial implementation should be inherited. Together these two constructs let you express the structural contracts at the heart of your domain without locking down every implementation detail — exactly the kind of modeling that bridges analysis and architecture.