@startuml

class Space

abstract class Shape

abstract class SolidOfRevolution

class Sphere
class Cylinder
class Cube
class SquarePyramid

interface HasWeight

Shape -left-o Space

SolidOfRevolution   <|-up- Shape
    Sphere          <|-up- SolidOfRevolution
    Cylinder        <|-up- SolidOfRevolution

Cube                <|--up- Shape
SquarePyramid       <|--up- Shape
TriangularPyramid   <|--up- Shape

Sphere              -down-.> HasWeight
Cylinder            -down-.> HasWeight
Cube                -down-.> HasWeight
SquarePyramid       -down-.> HasWeight
TriangularPyramid   -down-.> HasWeight

class Space
{
    - ArrayList<Shape> shapes
    + ArrayList<Shape> getShapes()
    + void add(Shape shape)
    + void delete(Shape shape)
    + double getTotalVolume()
    + double getTotalSurfaceSquare()
    + void scaleShapes(double num)
    + ArrayList<Shape> filterBy(Predicate<Shape> predicate)
    + ArrayList<Shape> sortedBy(Comparator<Shape> comparator)
}

abstract class Shape
{
    + double getSurfaceSquare()
    + double getVolume()
}

abstract class SolidOfRevolution
{
    - double radius
    + double getRadius()
    + void setRadius(double radius)
}

class Sphere
{
    - double weight
    + void Sphere(double radius)
}

class Cylinder
{
    - double weight
    - double height
    + void Cylinder(double height, double radius)
    + double getHeight()
    + void setHeight(double height)
}

class Cube
{
    - double weight
    - double edgeLength
    + void Cube(double edgeLength)
    + double getEdgeLength()
    + void setEdgeLength(double edgeLength)
}

class SquarePyramid
{
    - double weight
    - double edgeLength
    - double height
    + void SquarePyramid(double height, double edgeLength)
    + double getEdgeLength()
    + void setEdgeLength(double edgeLength)
    + double getHeight()
    + void setHeight(double height)
}

class TriangularPyramid
{
    - double weight
    - double edgeLength
    - double height
    + void TriangularPyramid(double edgeALength, double height)
    + double getEdgeLength()
    + void setEdgeLength(double edgeLength)
    + double getHeight()
    + void setHeight(double height)
}

interface HasWeight
{
    + double getWeight()
    + void setWeight(double weight)
    + double getDensity()
}

@enduml
