Class diagram

A class is a category of entities that share common attributes and operations. The class diagram shows a set of classes, interfaces, as well as their relationship. They are used for modeling object-oriented systems (for their static representation).

1. Basic elements

A class is a description of a collection of objects with the same attributes, operations, relationships, and semantics.

Graphically, the class is depicted as a rectangle divided into 3 blocks by horizontal lines:

  • class name 
  • class attributes (properties) 
  • class operations (methods)

Visibility for fields and methods is indicated as a left character in a string with the name of the corresponding element.

Each class must have a name that distinguishes it from other classes. The name is a text string. The class name may consist of any number of letters, numbers and punctuation marks (except for the colon and period) and can be written in several lines.

In practice, short class names are usually used. Each word in the class name is traditionally capitalized (Camel Case), such as Sensor or TemperatureSensor.

An attribute (property) is a named property of a class that describes the range of values that an attribute instance can take. A class can have any number of attributes or not have any. In the latter case, the attribute block is left blank.

An attribute represents some property of a simulated entity that all objects of a given class possess. An attribute name, like a class name, can be text. In practice, one or more short nouns are used to name an attribute, expressing a certain property of the class to which the attribute belongs.

You can clarify the specification of an attribute by specifying its type, multiplicity (if the attribute is an array of some values), and the initial default value.

Static class attributes are indicated by underscores.

An operation (method) is an implementation of a class method. A class can have any number of operations or not have any methods at all. The set of operations defines the functional aspect of class behavior

Graphically, the operations are presented in the lower block of the class description.

Only the names of operations are allowed. The name of the operation, like the name of the class, must be text.

In practice, short verb constructions are used that describe some behavior of the class to which the operation belongs. Usually, every word in the name of the operation is capitalized, except for the first, for example, move or isEmpty (check for emptiness).

Abstract class methods are indicated in italics.

Static class methods are indicated by underscores.

Representing a class, it is not necessary to show all its attributes and operations at once. For a particular representation, as a rule, only a part of the attributes and operations of a class is essential, therefore a simplified representation of the class is allowed when only some of its attributes are selected.

Relationship between classes

There are four types of lrelations in UML: 

  • Dependency 
  • Association 
  • Generalization 
  • Implementation 

These relationships are the basic building blocks for describing relationships in UML, used to develop well-consistent models.

Dependency – the relationship between two or more elements of a model in which one element uses other(s) element(s) for its implementation, so if one (independent) element changes then it can lead to a change in another (dependent) element.
Graphically this relationship is represented by a dashed line, sometimes with an arrow, directed towards the entity on which another one depends; possibly with a label.

Dependency is a kind of usage relationship, meaning that when a dependency relationship exists between two or more objects, the object needs to know about the other object(s) which it depends on.
 An association is a structural relationship between elements in the model that describes a set of relationships that exist between objects.

The association shows that the objects of one entity (class) are connected with the objects of another entity in such a way that you can move from objects of one class to another. 

You can give a name to the Association. In the unidirectional association view, an arrow is added to indicate the direction of the association.

Double associations are represented by a line without arrows at the ends connecting the two class blocks.

An association can be named, and then at the ends of the line representing it, roles, accessories, indicators, multipliers, visibilities or other properties will be signed.

Association plurality is a range of integer numbers that indicates the possible amount of related objects.

Aggregation is a special kind of association representing the structural connection of the whole with its parts. As a type of association, aggregation can be named. A single aggregation relationship cannot include more than two classes (container and content).

Aggregation occurs when one class is a collection or container of others. Moreover, by default, aggregation is called aggregation by reference, that is, when the lifetime of the contained classes does not depend on the lifetime of the class containing them. If the container is destroyed, then its contents are not.
Graphically, aggregation is represented by an empty rhombus on a block of the class “whole”, and a line going from this rhombus to the class “part”.

A Composition is a more stringent variant of aggregation. Also known as aggregation by value.

A Composition is a form of aggregation with clearly defined ownership relations and the coincidence of the lifetime of parts and the whole. The composition has a rigid dependence on the lifetime of instances of the container class and instances of the contained classes. If the container is destroyed, then all its contents will also be destroyed.
Graphically it is represented by a filled diamond.

Generalization – expresses a specialization or inheritance in which a specialized element (descendant) is built according to the specifications of a generalized element (parent). The descendant shares the structure and behavior of the parent.
Graphically, the generalization is presented in the form of a solid line with an empty arrow pointing to the parent.

An implementation is a semantic connection between classes when one of them (the provider) defines an agreement, which the second (the client) must adhere to. These are the relationships between the interfaces and the classes that implement these interfaces. This is a kind of whole-to-part relationship. A provider is typically represented by an abstract class.
Graphically implementation is represented by a dashed arrow. The triangle indicates the supplier, and the second end of the dashed line indicates the customer.

2. Syntax 

Classes declaration

Use the keyword сlass to declare a new сlass

Код скопирован
  • @startuml
  • Class Dummy
  • Class Flight
  • @enduml

Use the : symbol to declare Class Attributes and Methods

To declare properties and methods, you can use the : symbol, followed by the name of the field or method. To define a method, you need to add brackets (), for a property – []. The system detects methods and properties by brackets.

In addition, you can group all fields and methods between curly braces {}

Код скопирован
  • @startuml
  • Object <|– ArrayList
  • Object : equals()
  • ArrayList : Object[] elementData
  • ArrayList : size()
  • class Dummy
  • {
  • String data
  • void methods()
  • }
  • class Flight
  • {
  • flightNumber : Integer
  • departureTime : Date
  • }
  • @enduml

You can use {field} and {method} keywords to define properties and methods: 

Код скопирован
  • @startuml      
  • class Dummy {  
  • {field} A field (despite parentheses)  
  • {method} Some method 
  • @enduml 

When defining methods and attributes, you can use the visibility symbols shown in the table below:

  • - – private
  • # – protected
  • ~ – package private
  • + – public 
Код скопирован
  • @startuml  
  • class Dummy {  
  • -field1  
  • #field2  
  • ~method1()  
  • +method2()  
  • }  
  • @enduml 

You can hide the symbols with instruction skinparam classAttributeIconSize 0:

Код скопирован
  • @startuml 
  • skinparam classAttributeIconSize 0  
  • class Dummy { -field1  
  • #field2 
  • ~method1() +method2()  
  • }  
  • @enduml 

With modifiers {static} and {abstract} you can declare Class static and abstract methods, they will be shown with underlined (static) and italic (abstract) style correspondingly.

You can put these modifiers either at the beginning or at the end of the string. Also you can use {classifier} as a substitution for {static}

Код скопирован
  • @startuml  
  • class Dummy {  
  • {static} String id  
  • {abstract} void methods()  
  • }  
  • @enduml 

To declare an abstract class use keywords abstract or abstract class. In this case, the class name will have an italic font style.

Код скопирован
  • @startuml                                     
  • abstract class Dummy { 
  • {static} String id 
  • {abstract} void methods() 
  • @enduml

If you need to use non-literal characters in the name of a class (or another object), there are 2 ways:

  • The askeyword in a class definition 
  • Quotes around the class name
Код скопирован
  • @startuml
  • class “This is my class” as class1 
  • class class2 as “It works this way too” 
  • @enduml 

By default, methods and fields are automatically grouped by PlantUML. 
To define your order of fields and methods, you can use separators: -.. ,==, __

You can insert headers inside the delimiters: 

Код скопирован
  • @startuml 
  • class Foo1 { 
  • You can use 
  • several lines 
  • .. 
  • as you want 
  • and group 
  • == 
  • things together. 
  • __ 
  • You can have as  
  • many groups 
  • as you want 
  • — 
  • End of class 
  • class User { 
  •  
  •  
  • .. Simple Getter .. 
  • + getName() 
  • + getAddress() 
  • .. Some setter .. 
  • + setName() 
  • __ private data __ 
  • int age 
  • — encrypted — 
  • String password 
  • @enduml 

Manage your class visibility with the show /hide commands.

The default instruction is hide empty members. The instruction will hide attributes or methods if they are empty.

 Instead of empty members, you can use: 

  • empty fields or empty attributes for empty fields,
  • empty methods for empty methods,
  • fields or attributes that hide the fields, even if they have been described,
  • methods that will hide methods, even if they have been described,
  • members that hide fields and methods, even if they have been described,
  • circle for round characters before the class name,
  • stereotype for the template

You can also specify a keyword immediately after hide or show: 

  • class for all classes,
  • interface for all interfaces
  • enum for all listings,
  • <> for classes to which the template is applied using foo1,
  • name of an existing class name.

You can use several show/hide commands to define a large set of rules and exceptions.

Код скопирован
  • @startuml  
  • class Dummy1 {                              
  • +myMethods()  
  • }  
  • class Dummy2 { 
  • +hiddenMethod()  
  • }  
  • class Dummy3 <<Serializable>> {  
  • String name  
  • }  
  • hide members  
  • hide <<Serializable>> circle  
  • show Dummy1 methods  
  • show <<Serializable>> fields  
  • @enduml

Use show hide instructions to hide classes

Код скопирован
  • @startuml                             
  • class Foo1 
  • class Foo2 
  • Foo2 *– Foo1 
  • hide Foo2 
  • @enduml

Templates are defined by the class, << and >> keywords. 

If a class needs a specific label, it can be created using the characters << () >> as in the example: 

Код скопирован
  • @startuml 
  • class System << (S,#FF7700) Singleton >> 
  • class Date << (D,orchid) >> 
  • @enduml

Relations between classes

Relations between classes are defined using the following characters: 

  • <|-- – Extension 
  • *-- – Composition
  • o-- – Aggregation 

You can replace – with .. to create a dashed line. 

Код скопирован
  • @startuml
  • Class01 <|– Class02
  • Class03 *– Class04
  • Class05 o– Class06
  • Class07 .. Class08
  • Class09 Class10
  • @enduml
Код скопирован
  • @startuml
  • Class11 <|.. Class12
  • Class13 –-> Class14
  • Class15 ..> Class16
  • Class17 ..|> Class18
  • Class19 <–-* Class20
  • @enduml
Код скопирован
  • @startuml
  • Class21 #– Class22
  • Class23 x– Class24
  • Class25 }– Class26
  • Class27 +– Class28
  • Class29 ^– Class30
  • @enduml

You can add a label to the relationship. Use the symbol : and put the text of the label after it.

You can use double quotation marks “” to indicate the number of elements on each side of the relationship.

Код скопирован
  • @startuml
  • Class01 “1” *– “many” Class02 : contains
  • Class03 o– Class04 : aggregation
  • Class05 –> “2” Class06
  • @enduml

By default, relationships between classes have two dashes – and are vertically oriented. It is possible to create a horizontal connection using a single dash (or dot) like this:

Код скопирован
  • @startuml
  • Room o- Student
  • Room *– Chair
  • @enduml

You can change the direction of the arrows by reversing the connection (Room -o Student Room – * Chair), or use the keywords left, right, up or down inside the arrow:

Код скопирован
  • @startuml
  • foo –left-> dummyLeft
  • foo –right-> dummyRight
  • foo –up-> dummyUp
  • foo –down-> dummyDown
  • @enduml

The Extension and Implementation relations can be creared using keywords Extends and Implements:

Код скопирован
  • @startuml
  • class ArrayList implements List
  • class ArrayList extends AbstractList
  • @enduml

You can specify the class association after the relationship between the two classes has been defined, as in the example:

Код скопирован
  • @startuml
  • class Student {
  • Name
  • }
  • Student “0..*” – “1..*” Course
  • (Student, Course) .. Enrollment
  • class Enrollment {
  • drop()
  • cancel()
  • }
  • @enduml

Notes

Notes can be created with the help of the next keywords: note left of, note right of, note top of, note bottom of.

Also, you can assign a note the last defined class using the keywords note left, note right, note top, note bottom.

Using the note keyword, it is easy to create a note without an anchor, and then, using the .. symbol, attach it to other objects.

Код скопирован
  • @startuml
  • class Object << general >>
  • Object <|— ArrayList
  • note top of Object : In java, every class\nextends this one.
  • note “This is a floating note” as N1
  • note “This note is connected\nto several objects.” as N2
  • Object .. N2
  • N2 .. ArrayList
  • class Foo
  • note left: On last defined class
  • @enduml

It is possible to add a note to the link right after declaring the link using the keyword note on link

You can also use note left on link, note right on link, note top on link, note bottom on link if you want to change the relative position of the note with the caption.

Код скопирован
  • @startuml
  • class Dummy
  • Dummy –> Foo : A link
  • note on link #red: note that is red
  • Dummy –> Foo2 : Another link
  • note right on link #blue
  • this is my note on right link
  • and in blue
  • end note
  • @enduml

Packeges

You can define a package using the package keyword, with the option to declare its background color using the html color code or its name.

Please note that package definitions may be nested. 

Код скопирован
  • @startuml
  • package “Classic Collections” #DDDDDD {
  • Object <|– ArrayList
  • }
  • package net.sourceforge.plantuml {
  • Object <|– Demo1
  • Demo1 *- Demo2
  • }
  • @enduml

Various styles for packages are available. You can set default styles using the instruction: skinparam packageStyle, or apply templates to the package:

Код скопирован
  • @startuml
  • scale 750 width
  • package foo1 <<Node>> {
  • class Class1
  • }
  • package foo2 <<Rectangle>> {
  • class Class2
  • }
  • package foo3 <<Folder>> {
  • class Class3
  • }
  • package foo4 <<Frame>> {
  • class Class4
  • }
  • package foo5 <<Cloud>> {
  • class Class5
  • }
  • package foo6 <<Database>> {
  • class Class6
  • }
  • @enduml

You can establish connections between packages: 

Код скопирован
  • @startuml
  • skinparam packageStyle rectangle
  • package foo1.foo2 {
  • }
  • package foo1.foo2.foo3 {
  • class Object
  • }
  • foo1.foo2 +– foo1.foo2.foo3
  • @enduml

If you don’t need a package, but just want to group classes as if they are in a package, then you can use the keyword together.

Код скопирован
  • @startuml
  • class Bar1
  • class Bar2
  • together {
  • class Together1
  • class Together2
  • class Together3
  • }
  • Together1 – Together2
  • Together2 – Together3
  • Together2 -[hidden]–> Bar1
  • Bar1 -[hidden]> Bar2
  • @enduml