OOP Areas and Volumes




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. All of the 2D Shape Classes implement the Shape2D Interface. All of the 3D Classes extend one of the 2D Classes, therefore, they indirectly implement the Shape2D Interface. Additionally, all of the 3D Classes implement the Shape3D Interface.


These are the 2D Classes


These are the 3D Classes


Implementing an Interface in a Class means that your Class must use the methods and functions stipulated in the Interface. It also means that any of the nine Core Shape Classes can be created as an Object of type Shape2D, and the six 3D Core Shape Classes can be created as an Object of type Shape3D.


The Shape2D Interface

Public Interface Shape2D

    Function getArea() As Decimal

End Interface

The Shape3D Interface

Public Interface Shape3D

    Function getVolume() As Decimal

End Interface

The Core Classes

Circle

''' <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

Rectangle

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

    Public l, w As Decimal

    Public Sub New(l As Decimal, w As Decimal)
        Me.l = l
        Me.w = w
    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 Me.l * Me.w
    End Function

End Class

Triangle

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

    Public a, b, c As Decimal

    Public Sub New(a As Decimal, b As Decimal, c As Decimal)
        Me.a = a
        Me.b = b
        Me.c = c
    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
        Dim s As Decimal = CDec((Me.a / 2) + (Me.b / 2) + (Me.c / 2))
        Return CDec(Math.Sqrt(s * ((s - Me.a) * (s - Me.b) * (s - Me.c))))
    End Function

End Class

Cone

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

    Public h As Decimal

    Public Sub New(h As Decimal, r As Decimal)
        MyBase.New(r)
        Me.h = h
    End Sub

    ''' <summary>
    ''' Overriden getArea function
    ''' </summary>
    ''' <returns>Surface area of shape with specified dimensions</returns>
    Public Overrides Function getArea() As Decimal
        Return CDec(Math.PI * MyBase.r * (MyBase.r + Math.Sqrt(Me.h ^ 2 + Me.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 ^ 2 * Me.h) / 3)
    End Function

End Class

Cylinder

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

    Public h As Decimal

    Public Sub New(h As Decimal, r As Decimal)
        MyBase.New(r)
        Me.h = h
    End Sub

    ''' <summary>
    ''' Overriden getArea function
    ''' </summary>
    ''' <returns>Surface area of shape with specified dimensions</returns>
    Public Overrides Function getArea() As Decimal
        Return CDec(2 * Math.PI * MyBase.r * Me.h + 2 * 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 ^ 2 * Me.h)
    End Function

End Class

Sphere

''' <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

Cuboid

''' <summary>
''' 3D Cuboid class
''' </summary>
Public Class Cuboid
    Inherits Rectangle
    Implements Shape3D

    Public h As Decimal

    Public Sub New(l As Decimal, w As Decimal, h As Decimal)
        MyBase.New(l, w)
        Me.h = h
    End Sub

    ''' <summary>
    ''' Overriden getArea function
    ''' </summary>
    ''' <returns>Surface area of shape with specified dimensions</returns>
    Public Overrides Function getArea() As Decimal
        Return CDec(MyBase.getArea() * 2 + MyBase.l * Me.h * 2 + MyBase.w * Me.h * 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(MyBase.getArea() * Me.h)
    End Function


End Class

Prism

''' <summary>
''' 3D Prism class
''' </summary>
Public Class Prism
    Inherits Triangle
    Implements Shape3D

    Public l As Decimal

    Public Sub New(l As Decimal, a As Decimal, b As Decimal, c As Decimal)
        MyBase.New(a, b, c)
        Me.l = l
    End Sub

    ''' <summary>
    ''' Overriden getArea function
    ''' </summary>
    ''' <returns>Surface area of shape with specified dimensions</returns>
    Public Overrides Function getArea() As Decimal
        Return CDec(MyBase.getArea() * 2 + MyBase.a * Me.l + MyBase.b * Me.l + MyBase.c * Me.l)
    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(MyBase.getArea() * Me.l)
    End Function

End Class

Pyramid

''' <summary>
''' 3D Pyramid class
''' </summary>
Public Class Pyramid
    Inherits Triangle
    Implements Shape3D

    Public h As Decimal
    Public sides As Integer

    Public Sub New(h As Decimal, b As Decimal, bc As Decimal, s As Decimal)
        MyBase.New(b, bc, bc)
        Me.h = h
        Me.sides = CInt(s)
    End Sub

    ''' <summary>
    ''' Overriden getArea function
    ''' </summary>
    ''' <returns>Surface area of shape with specified dimensions</returns>
    Public Overrides Function getArea() As Decimal
        Select Case Me.sides
            Case 3
                Return CDec(getBaseArea(MyBase.a) + MyBase.getArea() * 3)
            Case 4
                Return CDec(MyBase.a ^ 2 + 2 * MyBase.a * Math.Sqrt(Me.h ^ 2 + MyBase.a ^ 2 / 4))
        End Select
        Return 0D
    End Function

    ''' <summary>
    ''' Implemented getVolume function
    ''' </summary>
    ''' <returns>Volume of shape with specified dimensions</returns>
    Public Function getVolume() As Decimal Implements Shape3D.getVolume
        Select Case Me.sides
            Case 3
                Return CDec((getBaseArea(MyBase.a) * Me.h) / 3)
            Case 4
                Return CDec(((MyBase.a ^ 2) * Me.h) / 3)
        End Select
        Return 0D
    End Function

    ''' <summary>
    ''' getBaseArea helper function
    ''' </summary>
    ''' <param name="b"></param>
    ''' <returns>3 sided pyramid base area</returns>
    Private Function getBaseArea(b As Decimal) As Decimal
        Dim s As Decimal = CDec((b * 3) / 2)
        Return CDec(Math.Sqrt(s * ((s - b) * (s - b) * (s - b))))
    End Function

End Class



The Coordinating Class

User input in the Form is passed to the Coordinating Class, which creates a new instance of the correct Class, as directed by user input. The results of the calculations are displayed in a Label at the bottom of the Form.

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(ByVal selectedClass As String, ByVal 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}2"
        Dim aClass2 As Shape3D = TryCast(aClass, Shape3D)
        If aClass2 IsNot Nothing Then
            msg &= $"{Environment.NewLine}Volume: {aClass2.getVolume:n2}3"
        End If

        Return msg

    End Function

End Class


Taking it further

This example demonstrates OOP, Substitution, and Reflection. An OOP application uses pre-defined Objects (The Core Shape Classes). Substitution is where you can Cast any of those Core Shape Classes as an Object of type Shape2D. Reflection is used in the Coordinating Class (Calculator Class) to create an instance of a Class from a String name.


This example is available for download here...






Try it now...