UML: Class & Object Diagrams

Inheritance & Generalization

18 min Lesson 5 of 10

Inheritance & Generalization

One of the most powerful ideas in object-oriented modeling is the ability to say that one class is a kind of another class. This relationship is called generalization in UML (or inheritance in programming). It captures the real-world fact that many things in a domain share common properties, while still having their own distinguishing features.

As a systems analyst, recognizing generalization opportunities lets you build cleaner, less redundant models — and signals to developers exactly how the class hierarchy should be coded.

The Notation: Hollow Triangle Arrow

In a UML class diagram, generalization is drawn as a solid line ending in a hollow (unfilled) triangle that points toward the parent class (also called the superclass or general class). The child class (the subclass or specialized class) is at the tail of the arrow.

  • The parent class holds attributes and operations shared by all subclasses.
  • Each subclass inherits everything from the parent and adds its own unique attributes or operations.
  • A subclass is a parent — a Doctor is a Person, a SavingsAccount is an Account.
Generalization vs. Inheritance: UML uses the term generalization for the diagram relationship; programming languages call the same concept inheritance. Both describe the same is-a structure. In analysis, prefer the term "generalization" to stay language-neutral.

A Clinic Booking Example

Consider a clinic scheduling system. Every person in the system — whether a patient or a staff member — has a name, a date of birth, and a phone number. But patients have insurance details, while doctors have a specialization. This is a classic generalization hierarchy.

Generalization hierarchy: Person → Patient and Doctor Person - name: String - dateOfBirth: Date - phone: String Patient - insuranceNumber: String + bookAppointment() + cancelAppointment() Doctor - specialization: String + viewSchedule() + prescribeMedication() Patient and Doctor inherit name, dateOfBirth, and phone from Person
Generalization hierarchy: Patient and Doctor both inherit shared attributes from Person. Hollow triangles point to the parent class.

Reading this diagram: the hollow triangle on the line from Patient to Person says "Patient is a kind of Person." The same logic applies to Doctor. Neither Patient nor Doctor need to redeclare name, dateOfBirth, or phone — they inherit those from Person.

Multi-Level Hierarchies

Generalization can span more than one level. In an online store, a Product can be specialized into PhysicalProduct and DigitalProduct. A PhysicalProduct can be further specialized into Book and Electronics. This creates a tree of increasing specificity.

Multi-level generalization: Product hierarchy in an online store Product - productId: Integer - name: String - price: Decimal PhysicalProduct - weight: Decimal + calculateShipping() DigitalProduct - fileFormat: String + generateDownloadLink() Book - isbn: String - author: String Electronics - warranty: Integer - brand: String
Multi-level generalization in an online store. Book and Electronics inherit from PhysicalProduct, which itself inherits from Product.

A Book instance therefore carries: productId, name, price (from Product), weight and calculateShipping() (from PhysicalProduct), and its own isbn and author. This layered inheritance is read by tracing the hollow triangles upward.

How to Spot Generalization in Requirements

When reading a requirements document or interviewing stakeholders, watch for these language patterns:

  • "There are two types of account: savings and checking."Account is the parent.
  • "Both full-time and part-time employees have an employee ID and a salary."Employee is the parent.
  • "A manager is an employee who also supervises a team."Manager inherits from Employee.

The signal phrase is "is a" or "is a type of". If you can say "X is a Y" and it holds true in every context, a generalization relationship belongs in your model.

Analyst tip — the substitution test: Before drawing a generalization arrow, apply the Liskov substitution principle informally: anywhere the parent class appears in the system, you should be able to substitute a subclass without breaking anything. If that is true, the hierarchy is valid. If not, the relationship might be an association rather than generalization.

Abstract Classes

Sometimes the parent class exists only to share structure — you never create an instance of it directly. In UML, such a class is marked abstract by writing its name in italics (or appending the {abstract} constraint). In our clinic example, you never create a plain Person — every person in the system is specifically a Patient or a Doctor. Person would therefore be abstract.

Common mistake — deep hierarchies: It is tempting to keep specializing. Resist going beyond two or three levels unless the business domain genuinely requires it. Deep hierarchies are harder to maintain and often signal that some subclasses should instead be modeled with attributes (e.g., an employeeType attribute) rather than separate classes.

Notation Summary

  • Generalization arrow: solid line + hollow triangle pointing to the parent class.
  • Parent (superclass / general class): holds shared attributes and operations.
  • Child (subclass / specialized class): inherits everything from the parent; adds its own members.
  • Abstract class: name in italics or {abstract} — never instantiated directly.
  • Reading direction: follow the hollow triangle upward to find the parent.

Mastering generalization in class diagrams prepares you to model the next layer of complexity: in Lesson 6 you will see association classes and dependencies, which handle relationships that carry their own attributes or represent usage rather than structure.