5.2. UML Class Diagrams

5.2.1. Basic Class Diagram

Here is a quick example of a basic UML class diagram for a Java class named Person in the cs1302.example package:

hide circle
skinparam classAttributeIconSize 0
set namespaceSeparator none

class cs1302.example.Person {
  -name: String
  -age: int
  {static} -personCounter: int
  <<new>> +Person(name : String, age : int)
  +getName() : String
  +getAge() : int
  {static} +getPersonCount() : int
}

A class diagram visually describes a reference type (e.g., a class) and consists of a rectangle broken up vertically into three sections, from top to bottom, to describe the name, variables, and methods of the reference type, respectively. Empty sections can be omitted. Private and public visibility are denoted using - and +, respectively, and static members are underlined. Here is a breakdown of the the three sections of a UML class diagram along with additional information related to the example:

  1. Class name. The first section contains the class name.

    • In the example above, the fully qualified name of the class is used. If multiple classes are given and assumed to be in the same package, then the simple name may be used here instead and the individual rectangles for each class can be grouped into a bigger rectangle with the package name.

    • You can include a + before a class name to indicate that it is public; however, all classes in a UML class diagram are assumed to be public, unless indicated otherwise.

  2. Variables. The second section contains descriptions for the variables and constants of the class. In UML, these are referred to as attributes.

    • In the example above, there are two private instance variables and one private static variable.

    • The data type for a variable is indicated after its name, and the name and type are separated visually using a colon.

  3. Methods. The third section contains descriptions for the constructors and methods of the class. In UML, these are referred to as operations.

    • In the example above, there is one public constructor (indicated using <<new>>), two public instance methods, and one public static method.

    • The return type for a method is indicated after its parameter list, and the parameter list and return type are separated visually using a colon. Return types for constructors are typically omitted.

Review Question

In your notes, write the skeleton code for the Person class shown in the example above. Once you are done, compare it to the sample solution below.

Sample Solution (Don’t open until completing the question above)
package cs1302.example;

public class Person {

    private String name;
    private int age;
    private static int personCounter;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
        Person.personCounter += 1;
    } // Person

    public String getName() {
        return this.name;
    } // getName

    public int getAge() {
        return this.age;
    } // getAge

    public static int getPersonCount() {
        return Person.personCounter;
    } // getPersonCount

} // Person

5.2.2. Visibility

The Java programming language supports four standard visibilities, and all four visibilities can be indicated in a UML class diagram using a symbol:

Visibility Name

Modifier Keyword

UML Symbol

private

private

-

package private

~

protected

protected

#

public

public

+

The package private and protected visibilities will be introduced and discussed in another chapter dedicated to visibility in Java.

5.2.3. Stereotypes

A stereotype is piece of text enclosed in angle brackets that is included in a UML class diagram to to convey additional information. Here are some stereotypes that are commonly used when depicting Java reference types:

Stereotype

Description

<<new>>

Denotes a constructor.

<<abstract>>

Denotes an abstract class or method.

<<override>>

Denotes a method override.

<<interface>>

Denotes an interface.

<<final>>

Denotes a final member.

Note

Examples of these stereotypes will be included in other chapters.

5.2.4. Abstract Classes and Operations

The usual way to denote that a class or operation is abstract in a UML class diagram is to italicize the name of the class or operation. Sometimes this is impractical in situations where it is difficult to discern the difference between the normal lettering of a font and its italicized version. In such cases, the names might also be prefixed with an <<abstract>> stereotype to better communicate the intention to the viewer of the diagram.

To illustrate the differences, consider the following diagrams for a class named Shape:

hide circle
skinparam classAttributeIconSize 0
set namespaceSeparator none

abstract class Shape1 as "Shape"
class Shape2 as "Shape"

Example 1

hide circle
skinparam classAttributeIconSize 0
set namespaceSeparator none

abstract class Shape << abstract >> {}

Example 2

One of the class diagram variants shown in Example 1 has an italicized name to communicate to readers that the variant describes an abstract class; however, if we had not stated the difference between the diagrams explicitly, many readers would not have noticed this difference in italicization and incorrectly assumed that both examples depict a class that is not abstract. To mitigate this potential issue, we recommend and follow the convention of using the <<abstract>> stereotype to denote that something is abstract, as seen in Example 2.

Note

Abstract classes and method will be introduced and discussed in more detail in another chapter.

5.2.5. Associations

When you have more than one class in a diagram, you often want to express how they are associated. In UML, this is done with association arrows. While UML class diagrams support many different kinds of association arrows, the following are used in this book:

hide circle
skinparam classAttributeIconSize 0
set namespaceSeparator none

class ClassA
class ClassB

ClassA <-- ClassB : uses

class Parent
class Child

Parent <|-- Child : extends

interface SomeInterface << interface >>
class SomeClass

SomeInterface <|.. SomeClass : implements

Each association arrow in the example above is visually different from the others with respect to its line and arrowhead. It may seem pedantic, but the way in which an association arrow is drawn or displayed in a class diagram is very important, especially when its label is omitted, because it is intended to communicate relationship information to viewers. Here is a brief description of each arrow in the example:

Arrow

Line

Arrow Head

Summary

Concept

skinparam style strictuml
hide empty members
hide circle
left to right direction

class A
class B
B --> A

solid

open

B uses A

Dependency

skinparam style strictuml
hide empty members
hide circle
left to right direction

class A
class B
B --|> A

solid

unfilled triangle

B extends A

Inheritance

skinparam style strictuml
hide empty members
hide circle
left to right direction

class A
class B
B ..|> A

dashed

unfilled triangle

B implements A

Interface

Note

Inheritance and interfaces will be introduced and discussed in more detail in another chapter.