UML Class Diagram is one of the interactive graphs Understand can draw of your code — call trees, dependencies, control flow, and more.
UML Class Diagram
Languages: Ada, C#, C++, Java, Python, WebTargets: Architectures, Classes, Files, Packages, Record Types
Variants: Classic
Show a UML-style class diagram of a selected class, along with its base classes and subclasses.
For a class, show the UML-style class diagram of the selected class. For a file, architecture, or Python package, show the UML-style class diagram of all classes contained in it.
The main box lists the class's own fields and methods in UML notation —
+/#/- prefixes for public/protected/private,
name: type for fields (with an initializer after = when
there is one), and name(params) returnType for methods. Its
immediate base classes are added above the main box and its immediate subclasses
below, connected by a hollow-triangle inheritance arrow pointing from subclass
to base class. This only follows class inheritance (extends, or the
equivalent in other languages) — it doesn't follow interface implementation,
so a class's implemented interfaces never appear here.
See the Declaration graph for a more detailed view of the same class — it groups members the same way, but also includes nested types, and adds the interfaces a class implements (or, for an interface, the classes that implement it).
Rooted at the abstract class Shape below, the main box lists its
private, protected, and public members in UML notation. Entity, its
base class, is added above; Circle, its only subclass, is added below.
Although Shape also implements Drawable and
Renderable, neither interface appears, since this graph only follows
class inheritance.
See the following code and corresponding graph
public abstract class Entity {
private static int nextId = 0;
protected final int entityId;
protected Entity() {
this.entityId = ++nextId;
}
public int getId() { return entityId; }
public abstract String describe();
static int allocateId() { return ++nextId; }
}
public interface Drawable {
void draw();
double area();
default String drawDescription() { return "Drawable"; }
}
interface Renderable {
void render(float alpha);
boolean isVisible();
}
public abstract class Shape
extends Entity implements Drawable, Renderable {
public enum Visibility { VISIBLE, HIDDEN, CLIPPED }
public interface ShapeObserver {
void onShapeChanged(Shape shape);
}
public static int maxShapes = 1000;
public abstract double area();
public abstract void draw();
public double getX() { return x; }
public double getY() { return y; }
public void moveTo(double nx, double ny) {
x = nx; y = ny; updateBounds(); }
public Visibility visibility() { return visibility; }
public void setVisibility(Visibility v) { visibility = v; }
public void addObserver(ShapeObserver obs) { observers.add(obs); }
public boolean isVisible()
{ return visibility == Visibility.VISIBLE; }
public void render(float alpha) { if (isVisible()) draw(); }
public String describe() {
return getClass().getSimpleName() + "(" + x + "," + y + ")"; }
protected static class BoundingBox {
public double minX, minY, maxX, maxY;
BoundingBox(double x, double y, double w, double h) {
minX = x; minY = y; maxX = x + w; maxY = y + h;
}
}
protected double x, y;
protected Visibility visibility = Visibility.VISIBLE;
protected BoundingBox bounds;
protected abstract void updateBounds();
protected void notifyObservers() {
for (ShapeObserver o : observers) o.onShapeChanged(this);
}
private static class IdCounter {
private static int count = 0;
static int next() { return ++count; }
}
private int shapeId;
private int refCount = 0;
private List<ShapeObserver> observers = new ArrayList<>();
private void assignId() { shapeId = IdCounter.next(); }
private void retain() { refCount++; }
private void release() { if (--refCount < 0) refCount = 0; }
protected Shape(double x, double y) {
super();
this.x = x;
this.y = y;
assignId();
}
}
public class Circle extends Shape {
private double radius;
public Circle(double x, double y, double radius) {
super(x, y);
this.radius = radius;
}
public double getRadius() { return radius; }
public void setRadius(double r) { radius = r; updateBounds(); }
@Override
public double area() { return Math.PI * radius * radius; }
@Override
public void draw() { }
@Override
protected void updateBounds() {
bounds = new BoundingBox(
x - radius, y - radius, radius * 2, radius * 2);
}
}