File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Beginning Java and the fly likes Storing objects polymorphically in a Figure array Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Storing objects polymorphically in a Figure array" Watch "Storing objects polymorphically in a Figure array" New topic
Author

Storing objects polymorphically in a Figure array

Luke Stamper
Ranch Hand

Joined: Jun 19, 2011
Posts: 64
This is a homework I am having trouble on...We were given the base class by our professor and instructed to only worry about a circle and rectangle.

"In your derived classes, only implement draw and erase – not center. A rectangle needs length, height and position (x,y). A circle needs a radius and position. You are not going to actually draw anything – erase and draw should just write out that you are in them. Add all necessary additional constructors, variables and methods in the derived classes. Call super to get the base class constructor.

Write a test program to test your classes. Your test program must store your objects polymorphically in a Figure array and call center from each element. Your code should look like this for the polymorphic section:


Notice that we can store any derived type in a base class array! This means that no matter how many shapes we have, refreshing is simply:



Here is sample output given by my professor...

Creating a rectangle.
R1 position (4,25) height = 5,width = 10
Creating a circle.
C1 position (5,5) radius = 44

Polymorphic Output:
In Figure, calling erase, draw
In Circle - doing erase
In Circle - doing draw
In Figure, calling erase, draw
In Rectangle - doing erase
In Rectangle - doing draw"



So far, my code gives me 2 compiler errors...

--------------------Configuration: <Default>--------------------
F:\Object Java\Rectangle.java:10: error: Rectangle is not abstract and does not override abstract method erase() in Figure
public class Rectangle extends Figure{
^
F:\Object Java\Circle.java:10: error: Circle is not abstract and does not override abstract method erase() in Figure
public class Circle extends Figure{
^
2 errors


Additionally, I am stuck on the idea of "Notice that we can store any derived type in a base class array! This means that no matter how many shapes we have, refreshing is simply: for(int i=0 ; i < num; i++) shapes[i].draw();.

I am also having trouble deciphering how to obtain the same output given by my professor.


Could anyone point me in the right direction or help me with some pseudo code so I can figure this out?

John Jai
Bartender

Joined: May 31, 2011
Posts: 1776

The errors are self explanatory. Any class that extends an abstract class should implement the abstract methods. So you have to implement the draw() and erase() methods in the sub classes Rectangle and Circle.

Read the tutorial - Abstract Methods and classes
John Jai
Bartender

Joined: May 31, 2011
Posts: 1776
Additionally, I am stuck on the idea of "Notice that we can store any derived type in a base class array! This means that no matter how many shapes we have, refreshing is simply: for(int i=0 ; i < num; i++) shapes[i].draw();.

This sentence refers to polymorphism. The shapes array variable is of the type Figure and hence can refer either a Rectangle or a Circle. So when you call the draw() method on the base reference (shape variable) you in turn call the respective draw() methods of the corresponding sub class object it refers to.

In this case either a Rectangle or a Circle. So the code is written generic to call the draw() method and you don't need to say whether it's Rectangle's draw() or Circle's draw() method. It gets detected during run time.

And note that draw() method is declared as abstract in the base Figure class. That guarantees you to implement a sub class specific draw() method in the Rectangle and the Circle class.
Luke Stamper
Ranch Hand

Joined: Jun 19, 2011
Posts: 64
I added these to each of my subclasses (one for rectangle, one for draw).



This was my output...

--------------------Configuration: <Default>--------------------
In Figure, calling erase, draw
In Circle - Doing erase
In Circle - Doing draw
In Figure, calling erase, draw
In Rectangle - Doing erase
In Rectangle - Doing draw
Exception in thread "main" java.lang.NullPointerException
at TestFigure.main(TestFigure.java:24)

Process completed.

I'm not understanding how to call my circle/rectangle subclasses to print out position & radius for circle and position, height, & length for rectangle. If I try and do something like



it comes out like this...

Rectangle@1fee6fc
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18909
    
    8

That's the sort of thing you get if you don't override the toString() method in your classes. If you have to have your Rectangle object be output in a specific way, then provide it with a toString() method which returns a suitable String.
Luke Stamper
Ranch Hand

Joined: Jun 19, 2011
Posts: 64
I'm almost done. The idea is that the the new rectangle and circle will call the parameters from the super class and I will add the remaining parameters when I create a new object. Can anyone help?





--------------------Configuration: <Default>--------------------
F:\Object Java\TestFigure.java:14: error: constructor Rectangle in class Rectangle cannot be applied to given types;
Rectangle r1 = new Rectangle(5,4);
^
required: String,int,int,int,int
found: int,int
reason: actual and formal argument lists differ in length
F:\Object Java\TestFigure.java:16: error: constructor Circle in class Circle cannot be applied to given types;
Circle c1 = new Circle(44);
^
required: String,int,int,int
found: int
reason: actual and formal argument lists differ in length
2 errors
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39878
    
  28
Your Rectangle constructor requires different parameters from what you are passing. Your rectangle constructor is badly designed and ought to be changed. You don’t want a “super” and a subclass name. You have a name which is set in the superclass, so you pass super(name). Where on earth you get “R1” and 4 and 5 from?
You pass name and x and y unchanged to the superclass’ constructor. Get rid of the getSuperXXX methods because they are unnecessary; the getXXX methods are inherited by all subclasses anyway. If you want to be clever, mark the getXXX methods in the Figure class final, because you don’t want them overridden.
Luke Stamper
Ranch Hand

Joined: Jun 19, 2011
Posts: 64
I'm trying to reset x and y in each subclass with different values. That's where those came in.
Luke Stamper
Ranch Hand

Joined: Jun 19, 2011
Posts: 64
Also, I am getting the error

Exception in thread "main" java.lang.NullPointerException
at TestFigure.main(TestFigure.java:28)

I am not sure how to remedy this.
Luke Stamper
Ranch Hand

Joined: Jun 19, 2011
Posts: 64
I wanted to clarify what I am trying to do. I want the rectangle and circle class to each have a different (x,y) position. So in each class, I need to reset the values of X and Y from the superclass. I am having difficulty doing this.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39878
    
  28
Go through line 28 and see which objects you have put to the left of a . operator. One of them may be null. If you don’t work out which is null in a few minutes, post again with a few lines around no 28 in code tags.
Luke Stamper
Ranch Hand

Joined: Jun 19, 2011
Posts: 64
I believe the shapes array was null so I added c1 and r1.



Now my output is...

--------------------Configuration: <Default>--------------------
Creating a rectangle.
R1 position (0,0) height = 2 length = 3

Creating a circle.
C1 position (0,0) radius = 44.0

In Figure, calling erase, draw
In Circle - Doing erase
In Circle - Doing draw
In Figure, calling erase, draw
In Rectangle - Doing erase
In Rectangle - Doing draw
In Circle - Doing draw
In Rectangle - Doing draw

Process completed.


I am left trying to figure out how to ensure each shape gets a different position. X & Y in the super are set to 0, but I need to change for each subclass.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39878
    
  28
As for the null: whenever you create an array of reference types, it is filled with nulls as a default. If you don’t specifically fill the array with “real” references, you may suffer such an Exception.
Luke Stamper
Ranch Hand

Joined: Jun 19, 2011
Posts: 64
Thank you. Could you also shed some light on my issue of resetting the X,Y from the super class for the rectangle and square so each object can have a different position?
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39878
    
  28
You need to decide where you do and where you don’t want constructors.Now you can set speed and direction. Note the actions taken to ensure both speed and direction are within certain ranges.

Yes, this is relevant, because you now have a superclass with two int fields. You can forget about the Exception and Math.abs and the 360°, since you have no limits to the values you permit.
Now rewrite the Vehicle class, miss out all the bits you don’t need, and compare it with your Figure class.
You want constructors which will set up those two fields, so you write a constructor which sets up those two fields. You don’t want default values, so you get rid of any other constructors. You may have to amend other code which uses those constructors, which you are getting rid of. You do not want a constructor like this, because you do not want to default to all your vehicles doing 97mph eastward:If you found a constructor like that in the Vehicle class, and called new Bus(); anywhere, you get the default values. So you don’t want either of those constructors. If you have a constructor which gives you defaults you don’t want, get rid of it. That’s the only way to ensure nobody calls it by mistake.

Now let’s look at a possible subclassNote there is no turn method, nor speedUp, nor getSpeed, nor getDirection. Those are inherited from the Vehicle class. The only place you use super. is in the toString method, so you are adding “A Bus travelling at 97mph in direction 90°” to “with 127 passengers.”
And yes, it will say Bus, not Vehicle.

So we have a Bus class which inherits those features from its superclass. Now see if you can’t turn my Bus class into your Circle class. Only give it the constructors you want. Then you must pass parameters to those constructors, defining the x, y locations
Luke Stamper
Ranch Hand

Joined: Jun 19, 2011
Posts: 64
Got it! Thanks for your help, it is much appreciated.


Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39878
    
  28
In your centre() method, are you supposed to alter the x, y position?
By the way: it should be x and y, not X and Y, for the field names.

You can see how much of an improvement that latest code is if you compare it to the previous attempt. You have saved thirty lines Well done.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Storing objects polymorphically in a Figure array