Shape classes hierarchy

justlearning

Member
Joined
Dec 11, 2008
Messages
16
Programming Experience
Beginner
Hi guys I am sorry I do not know where to post this. If this is the wrong spot please let me know where you think I should have posted it and why.

I have an assignment that goes as follows:
Create a set of classes that use inheritance according to the following hierarchy:




Please note that your Shape class should contain only the following:

an x value – this is the horizontal location of the Shape
a y value – this is the vertical location of the Shape
a way to get and set each of these fields
a constructor that takes initial values for x and y
a ToString method that will return a description of the Shape as a String.
NOTE: At no time in this Project will you be writing code to draw any of the Shapes. Instead, you'll be using your classes to represent the Shape. If you have questions about this, please contact your instructor.

Once your Shape class is written, you'll write the Circle, Cylinder and Square classes, inheriting from the appropriate classes according to the diagram. Be sure that each class contains appropriate instance variables (based on the class type) and methods (a way to get and set each variable, appropriate constructors, a way to calculate area or volume and a ToString method).

When you have all of your classes complete, write a console application that creates a single array of Shape objects. Store at least two objects of type Circle, two of Cylinder and two of Square in your array. Be sure to prompt your user for the values of the variables. Once all objects have been created, use a loop to go through the array and print a description of each object by calling its ToString method.

Although not required to look this way, your program output might look like:

Please enter the x location of the first circle: 1
Please enter the y location of the first circle: 2
Please enter the radius of the first circle: 3

Please enter the x location of the second circle: 4
Please enter the y location of the second circle: 5
Please enter the radius of the second circle: 6



Please enter the x location of the first cylinder: 7
Please enter the y location of the first cylinder: 8
Please enter the radius of the first cylinder: 9
Please enter the height of the first cylinder: 10



Please enter the x location of the second cylinder: 11
Please enter the y location of the second cylinder: 12
Please enter the radius of the second cylinder: 13
Please enter the height of the second cylinder: 14



Please enter the x location of the first square: 15
Please enter the y location of the first square: 16
Please enter the length of the first square: 17



Please enter the x location of the second square: 18
Please enter the y location of the second square: 19
Please enter the length of the second square: 20

Your shapes are:
Circle at (1, 2) with radius 3 has area 28.26
Circle at (4, 5) with radius 6 has area 113.04
Cylinder at (7, 8) with radius 9, height 10 has volume 2543.4
Cylinder at (11, 12) with radius 13, height 14 has volume 7429.24
Square at (15, 16) with length 17 has area 289
Square at (18, 19) with length 20 has area 400
Press any key to continue

I have most of the code ( I think) but am having trouble with one spot. It says that I have to use a loop to go through the array and print a description of each object by calling its ToString method. I have the output using each class's ToString method but it isn't looped and I don't know how to do more than one instance of each shape. My output currently looks exactly like the above referenced example except for one key thing. It only has one instance of each shape.

My code is as follows:

Console Application
VB.NET:
Option Strict On
Module Module1
    Sub Main()
        Dim myshape As New Shape
        Dim mycircle As New Circle
        Dim mysquare As New square
        Dim mycylinder As New cylinder
        Dim result As String

        Console.Write("Please enter the x location of the first circle: ")
        mycircle.xvalue = Console.ReadLine
        Console.Write("Please enter the y location of the first circle: ")
        mycircle.yvalue = Console.ReadLine
        Console.Write("Please enter the radius of the first circle: ")
        mycircle.radius = CInt(Console.ReadLine)

        Console.WriteLine("")
        Console.Write("Please enter the x location of the first cylinder: ")
        mycylinder.xvalue = Console.ReadLine
        Console.Write("Please enter the y location of the first cylinder: ")
        mycylinder.yvalue = Console.ReadLine
        Console.Write("Please enter the radius of the first cylinder: ")
        mycylinder.radius = CInt(Console.ReadLine)
        Console.Write("Please enter the height of the first cylinder: ")
        mycylinder.height = CInt(Console.ReadLine)

        Console.WriteLine("")
        Console.Write("Please enter the x location of the first square: ")
        mysquare.xvalue = Console.ReadLine
        Console.Write("Please enter the y location of the first square: ")
        mysquare.yvalue = Console.ReadLine
        Console.Write("Please enter the length of the second square: ")
        mysquare.length = CInt(Console.ReadLine)

        Console.WriteLine("")
        Console.Write(myshape.mystringshape & vbCrLf & mycircle.mystringcircle & vbCrLf _
        & mycylinder.mystringcylinder & vbCrLf & mysquare.mystringsquare & vbCrLf)

        Console.WriteLine("Press any key to continue")
        result = Console.ReadLine

    End Sub

End Module

Classes ( Shape, Circle, Square, Cylinder)

VB.NET:
'Parent Class
Public Class Shape

    'Creates protected fields
    'Fields for shape(xvalue and yvalue)
    Protected m_xvalue As Integer
    Protected m_yvalue As Integer
    Public Sub New(ByVal xvalue As String, ByVal yvalue As String)
        m_xvalue = xvalue
        m_yvalue = yvalue
    End Sub

    Public Property xvalue()
        Get
            Return m_xvalue
        End Get
        Set(ByVal value)
            m_xvalue = value
        End Set
    End Property
    Public Property yvalue()
        Get
            Return m_yvalue
        End Get
        Set(ByVal value)
            m_yvalue = yvalue
        End Set
    End Property
    Sub New()
        MyBase.new()
    End Sub
    Public Sub New(ByVal xvalue As Double, ByVal yvalue As Double)
        MyBase.New()
        m_xvalue = xvalue
        m_yvalue = yvalue
    End Sub
    Public Function mystringshape() As String
        Return String.Format("Your shapes are: " & vbCrLf)
    End Function
End Class

'Child class
Public Class Circle
    Inherits Shape

    Public Sub New(ByVal radius As String)
        m_radius = radius
    End Sub

    Private m_radius As Integer
    Public Property radius() As Integer
        Get
            Return m_radius
        End Get
        Set(ByVal value As Integer)
            m_radius = value
        End Set
    End Property
    Public Sub area()
        Dim area As Integer
        area = radius ^ 2 * 3.14
    End Sub
    Sub New()
        MyBase.New()
    End Sub
    Public Function mystringcircle() As String
        Return ("Circle at (" & xvalue & ", " _
        & yvalue & ") with radius " & radius & " has area " _
        & radius ^ 2 & 3.14)
    End Function
End Class

Public Class square
    Inherits Shape

    Public Sub New(ByVal length As String)
        m_length = length
    End Sub
    Private m_length As Integer

    Public Property length() As Integer
        Get
            Return m_length
        End Get
        Set(ByVal value As Integer)
            m_length = value
        End Set
    End Property
    Public Sub area()

        Dim area As Integer

        area = length * length
    End Sub
    Sub New()
        MyBase.New()
    End Sub
    Public Function mystringsquare() As String
        Return ("Square at (" & xvalue & ", " & yvalue _
        & ") with length " & length & " has area " & length * length)
    End Function

End Class

Public Class cylinder
    Inherits Circle
    Public Sub New(ByVal height As String)
        m_height = height
    End Sub
    Private m_height As Integer
    Public Property height() As Integer
        Get
            Return m_height
        End Get
        Set(ByVal value As Integer)
            m_height = value
        End Set
    End Property
    Public Sub volume()

        Dim volume As Decimal
        volume = radius ^ 2 * 3.14 * height
    End Sub
    Sub New()
        MyBase.New()
    End Sub

    Public Function mystringcylinder() As String
        Return ("Cylinder at (" & xvalue & ", " & yvalue _
        & ") with radius " & radius & ", height " & height _
        & " has volume " & radius ^ 2 * 3.14 * height)
    End Function
End Class

Please let me know if you have any advice. Thanks so much!
 
The instructions state specifically:
When you have all of your classes complete, write a console application that creates a single array of Shape objects.
Where's your array? You need to start off with an empty array and each time you create a new shape you can use ReDim Preserve to expand the array by one element and then assign the new shape to that element. Once you're doing you use a For or For Each loop to visit each element in the array.
 
Okay, I am putting in my array and please don't be angry but I am not sure what the array should include. Should it be

Dim my array (2) as string
myarray(0) - circle
myarray(1) = square
myarray(2) = cylinder

or

Dim myArray(9) as string
myarray(0) = mycircle.xvalue
myarray(1) = mycircle.yvalue
myarray(2) = mycircle.radius
myarray(3) = mycylinder.xvalue
myarray(4) = mycylinder.yvalue
myarray(5) = mycylinder.radius
myarray(6) = mycylinder.height
myarray(7) = mysquare.xvalue
myarray(8) = mysquare.yvalue
myarray(9) = mysquare.length
 
It shouldn't be a String array for a start. The whole point of the array is to store Shape objects, so it must be a Shape array. The idea is that you create a Shape array and then each element can be any Shape, i.e. a Circle, a Cylinder or a Square. Once you've created all the different Shapes and added them all to the array then you're supposed to loop through the array and call ToString on each element. The result of ToString will depend on what type of Shape it is.

This is the point of this exercise: to see polymorphism in action. You have an array of Shapes that you call ToString on but the actual result depends what each individual Shape is. Always remember that programming doesn't exist in a vacuum. Programming models the real world. You could attach a hundred different printers to your computer and print a document. You don't care whether it's an inkjet, a laser, colour, monochrome, dot matrix even. As loong as it's a printer you can hook it up to your computer and print. As long as it's a Shape you can put it into a Shape array and call ToString on it, whether it's a Circle, a Square or a Cylinder.
 
Okay, so I have:

Dim shapearray() as shape = {mycircle, mycylinder, mysquare}

My problem is that I don't understand how to use an array with all of the clases. On top of that, I have to find a way to change "first" circle, "first" cylinder, "first" square to the "second" of each. I was wondering if you knew of a tutorial that may teach me this stuff. I have done arrays before but this seems so complicated. Anyway, thanks for the help.
 
Okay I think I am doing better.

Here is what I have now:

VB.NET:
Option Strict On
Module Module1
    Sub Main()
        Dim mycircle As New Circle
        Dim myshape(7) As Shape
        myshape(0) = New Shape
        myshape(1) = New Circle
        myshape(2) = New Circle
        myshape(3) = New cylinder
        myshape(4) = New cylinder
        myshape(5) = New square
        myshape(6) = New square



        Console.Write("Please enter the x value of the first circle: ")
        myshape(1).xvalue = Console.ReadLine
        Console.Write("Please enter the y value of the first circle: ")
        myshape(1).yvalue = Console.ReadLine
        Console.Write("Please enter the radius of the first circle: ")

        Console.WriteLine("")
        Console.Write("Please enter the x value of the second circle: ")
        myshape(2).xvalue = Console.ReadLine
        Console.Write("Pleae enter the y value of the second circle: ")
        myshape(2).yvalue = Console.ReadLine

        Console.WriteLine("")
        Console.Write("Please enter the x value of the first cylinder: ")
        myshape(3).xvalue = Console.ReadLine
        Console.Write("Please enter the y value of the first cylinder: ")
        myshape(3).yvalue = Console.ReadLine

        Console.WriteLine("")
        Console.Write("Please enter the x value of the second cylinder: ")
        myshape(4).xvalue = Console.ReadLine
        Console.Write("Please enter the y value of the second cylinder: ")
        myshape(4).yvalue = Console.ReadLine

        Console.WriteLine("")
        Console.Write("Please enter the x value of the first square: ")
        myshape(5).xvalue = Console.ReadLine
        Console.Write("Plese enter the y value of the first square: ")
        myshape(5).yvalue = Console.ReadLine

        Console.WriteLine("")
        Console.Write("Please enter the x value of the second square: ")
        myshape(6).xvalue = Console.ReadLine
        Console.Write("Please enter the y value of the second square: ")
        myshape(6).yvalue = Console.ReadLine

        Console.WriteLine(myshape(0).mystringshape)

        Console.Write("Press any key to continue")
        Console.Read()

    End Sub

End Module

Now my problem is that my new circle isn't inheriting the new circle properties (i.e. radius), my new cylinder isn't inheriting the new cylinder properties (i.e. radius and height) and the new square isn't inheriting the new square properties (i.e. length). Each of these are only inheriting the new shape properties.

Please help me I am getting desperate!
 
Your (array) variable is type Shape, so when you are using it you can only see Shape type members even if you have put an inherited class object there. To see the special type members you have to type cast that Shape object to a more specific type. This is done using DirectCast or CType functions, they take the object as first parameter and the requested type as second parameter.
VB.NET:
DirectCast(shapes(0), Circle).CircleMember = valeu
That said, you are here better off creating your object using a type specific variable, setting all properties, then assign that object to one of the array positions.
VB.NET:
Dim s As New Circle
s.x = value
s.y = value
s.z = value
shapes(0) = s
 
Hi John,

I tried this and just used my information

VB.NET:
Dim mycircle As New Circle
        mycircle.xvalue = value
        mycircle.yvalue = value
        mycircle.radius = value
        myshape(0) = mycircle

I assumed I would do this for each shape, the only problem is this:

VB.NET:
DirectCast(shapes(0), Circle).CircleMember = value

According to the project instructions I have to:
write a console application that creates a single array of shape objects

I figure I can do the myshape(i) = whatevershapethatisinthearray

but I don't know how I would do a direct cast in this way since the shapes(0), has to be whatever the shape class is for that particular shape.

Did I explain that right?

If not tell me and I will try again.

I really appreciate your help.

Thanks so much...
 
Why do you need to cast when using the other method? There is no conflict with the instructions here.
 
As John says, why do you need to cast at all if you follow his second advice? The idea is that you have a Shape array, you create various specific types of Shapes AND configure them before adding them to the array. You can then simply loop through the array and call ToString on each element. ToString is a member of the Shape class so you can access it without a cast. This is exactly what polymorphism is. You call ToString on each Shape without regard for its actual type, but it is the ToString method of individual object that gets invoked. Don't fight it. Just do as advised and it will work. :)
 
Back
Top