# Overview

This is an OOP Areas and Volumes Calculator. It consists of a core containing nine classes representing different geometric shapes. These shapes fall into two categories - 2D and 3D.

Figure 1. Core object diagram showing inheritance and implementation.

There are three classes that represent 2D shapes, that implement the Shape2D Interface. These are:
•  Circle - This contains a constructor with one Decimal parameter  - r (radius) and implements the getArea function. There are three classes that inherit Circle that implement the getVolume function from the Shape3D Interface, as well as overriding the base class getArea function:

• Cone - This contains a constructor with two Decimal parameters - r (radius) and h (height).
• Cylinder - This contains a constructor with two Decimal parameters - r (radius) and h (height).
• Sphere - This contains a constructor with one Decimal parameter  - r (radius).

• Rectangle - This contains a constructor with two Decimal parameters - l (length) and w (width) and implements the getArea function.The Cuboid class inherits this class and implements the getVolume function from the Shape3D Interface, as well as overriding the Rectangle class getArea function:

• Cuboid - This contains a constructor with three Decimal parameters - - l (length), w (width), and h (height).

• Triangle - This contains a constructor with three Decimal parameters - a (side A), b (side B), and c (side C) and implements the getArea function. There are two classes that inherit the Triangle class, both of which implement the getVolume function from the Shape3D Interface, as well as overriding the Triangle' getArea function:

• Prism - This contains a constructor with four Decimal parameters - l (length), a (side A), b (side B), and c (side C).
• Pyramid - This contains a constructor with four Decimal parameters -h (height), b (base length), bc (sides b and c), and s (number of sides).

There is a Calculator class that has a function - calculate, that is passed a className string parameter and a 2D object array parameter containing the contents of the DGV which is used for input. This method coordinates the creation of the shape classes through substitution and reflection and it returns a formatted string containing area and volume (if applicable).

## The Calculator class

`Public` `Class` ``` Calculator```

`    ``Dim` `variablesByName ``As` `New` ``` Dictionary(Of ````String````, ````Decimal``)`
`    ``Dim` `classesByName ``As` `New` ``` Dictionary(Of ````String````, ````String``)`

`    ``''' <summary>`
`    ``''' Sets up the two Dictionary objects`
`    ``''' </summary>`
`    ``Public` `Sub` ``` New````()`
`        ``variablesByName.Add(``"Length"``, 0D)`
`        ``variablesByName.Add(``"Width"``, 0D)`
`        ``variablesByName.Add(``"Height"``, 0D)`
`        ``variablesByName.Add(``"Radius"``, 0D)`
`        ``variablesByName.Add(``"SideA"``, 0D)`
`        ``variablesByName.Add(``"SideB"``, 0D)`
`        ``variablesByName.Add(``"SideC"``, 0D)`
`        ``variablesByName.Add(``"Base"``, 0D)`
`        ``variablesByName.Add(``"Sidelength"``, 0D)`
`        ``variablesByName.Add(``"Sides"``, 0D)`

`        ``classesByName.Add(``"Circle"````, ````"Circle"``)`
`        ``classesByName.Add(``"Rectangle"````, ````"Rectangle"``)`
`        ``classesByName.Add(``"Triangle"````, ````"Triangle"``)`
`        ``classesByName.Add(``"Cone"````, ````"Cone"``)`
`        ``classesByName.Add(``"Cylinder"````, ````"Cylinder"``)`
`        ``classesByName.Add(``"Sphere"````, ````"Sphere"``)`
`        ``classesByName.Add(``"Cuboid"````, ````"Cuboid"``)`
`        ``classesByName.Add(``"Prism"````, ````"Prism"``)`
`        ``classesByName.Add(``"3 Sided Pyramid"````, ````"Pyramid"``)`
`        ``classesByName.Add(``"4 Sided Pyramid"````, ````"Pyramid"``)`
`    ``End` `Sub`

`    ``''' <summary>`
`    ``''' Coordinates creation of classes by substitution and reflection.`
`    ``''' </summary>`
`    ``''' <param name="selectedClass"></param>`
`    ``''' <param name="cells"></param>`
`    ``''' <returns>A formatted string containing area and volume (if applicable)</returns>`
`    ``Public` `Function` ``` calculate(selectedClass ````As` `String````, cells(,) ````As` ``` Object````) ``As` `String`

`        ``For` `x ``As` `Integer` ``` = 0 ````To` ``` 3```
`            ``If` `Not` ``` cells(x, 0) ````Is` ``` Nothing``` `Then`
`                ``If` `Not` ``` cells(x, 1) ````Is` ``` Nothing``` `Then`
`                    ``Dim` `v ``As` `Decimal`
`                    ``If` `Decimal````.TryParse(cells(x, 1).ToString, v) ````Then`
`                        ``variablesByName(cells(x, 0).ToString) = v`
`                    ``Else`
`                        ``Return` `""`
`                    ``End` `If`
`                ``Else`
`                    ``Return` `""`
`                ``End` `If`
`            ``End` `If`
`        ``Next`

`        ``Dim` `parameters ``As` `New` ``` List(Of ````Decimal``)`
`        ``For` `Each` ``` kvp ````As` ``` KeyValuePair(Of ````String````, ````Decimal````) ````In` ``` variablesByName```
`            ``If` `kvp.Value > 0 ``Then`
`                ``parameters.Add(kvp.Value)`
`            ``End` `If`
`        ``Next`

`        ``For` `Each` ``` s ````As` ``` String``` `In` ``` variablesByName.Keys.ToList```
`            ``variablesByName(s) = 0D`
`        ``Next`

`        ``Dim` `aClass ``As` `Shape2D = ``DirectCast``(Activator.CreateInstance(Type.``GetType``(``"OOP_Areas_and_Volumes."` `& classesByName(selectedClass)), parameters.ConvertAll(``Function````(d) ````CObj``(d)).ToArray), Shape2D)`

`        ``Dim` `msg ``As` `String` ``` = \$````"Surface area: {aClass.getArea:n2}²"`
`        ``Dim` `aClass2 ``As` `Shape3D = TryCast(aClass, Shape3D)`
`        ``If` `aClass2 IsNot ``Nothing` `Then`
`            ``msg &= \$``"{Environment.NewLine}Volume: {aClass2.getVolume:n2}³"`
`        ``End` `If`

`        ``Return` `msg`

`    ``End` `Function`

`End` `Class`

### The (2D) Circle class

`''' <summary>`
`''' 2D Circle class`
`''' </summary>`
`Public` `Class` ``` Circle```
`    ``Implements` `Shape2D`

`    ``Public` `r ``As` `Decimal`

`    ``Public` `Sub` ``` New````(r ``As` `Decimal``)`
`        ``Me``.r = r`
`    ``End` `Sub`

`    ``''' <summary>`
`    ``''' Implemented getArea function`
`    ``''' </summary>`
`    ``''' <returns>Surface area of shape with specified dimensions</returns>`
`    ``Public` `Overridable` ``` Function``` `getArea() ``As` `Decimal` ``` Implements``` `Shape2D.getArea`
`        ``Return` `CDec````(Math.PI * ````Me``.r ^ 2)`
`    ``End` `Function`

`End` `Class`

### The (3D) Sphere class

`''' <summary>`
`''' 3D Sphere class`
`''' </summary>`
`Public` `Class` ``` Sphere```
`    ``Inherits` `Circle`
`    ``Implements` `Shape3D`

`    ``Public` `Sub` ``` New````(r ``As` `Decimal``)`
`        ``MyBase``.``New``(r)`
`    ``End` `Sub`

`    ``''' <summary>`
`    ``''' Overriden getArea function`
`    ``''' </summary>`
`    ``''' <returns>Surface area of shape with specified dimensions</returns>`
`    ``Public` `Overrides` ``` Function``` `getArea() ``As` `Decimal`
`        ``Return` `CDec````(4 * Math.PI * ````MyBase``.r ^ 2)`
`    ``End` `Function`

`    ``''' <summary>`
`    ``''' Implemented getVolume function`
`    ``''' </summary>`
`    ``''' <returns>Volume of shape with specified dimensions</returns>`
`    ``Public` `Function` ``` getVolume() ````As` ``` Decimal``` `Implements` ``` Shape3D.getVolume```
`        ``Return` `CDec````((Math.PI * ````MyBase``.r ^ 3 * 4) / 3)`
`    ``End` `Function`

`End` `Class`

# The GUI

The GUI consists of a Form containing a ComboBox for selecting shapes, a DataGridView for inputting dimensions, a Button to initiate the calculation process, and a Label for displaying output.

Figure 2. The form