Read through the code and answer the following. List all the statements where the datatype of a reference might not be an exact match with the datatype of the object that it refers to. This is a kind of polymorphism. In the containsPoint method of Circle, why are x and y in scope, even though they are not defined as instance variables in Circle.java? Notice that x and y are declared as ‘protected’ in GridItem. Change this to ‘private’ and recompile. How does the compiler respond? How could Abstract Methods have been used to make the code cleaner? How might an Interface have been used to structure the classes? - Modify GridItem class below to make GridItem an abstract class. Make its getArea and containsPoint methods abstract. public class GridItem { protected int x; protected int y; public int getX() {return x;} public void setX(int value) {x = value;} public int getY() {return y;} public void setY(int value) {y = value;} public double getArea() { return 0; } public boolean containsPoint(int xValue, int yValue) { return x == xValue && y == yValue; } } - Create a new class named Square that extends GridItem. Give it the instance variable ‘side’ instead of the rectangle’s height and width, or the circle’s radius. Also give it an appropriate constructor, and implementations of getArea and containsPoint. Instantiate some squares in the testing program to make sure it works class Main { public static void main(String[] args) { GridWriter gw = new GridWriter(40, 50); gw.add(new Circle(10, 10, 9)); gw.add(new Circle(25, 20, 12)); gw.add(new Circle(25, 20, 5)); gw.add(new Rectangle(25, 25, 20, 15)); gw.add(new Rectangle(5, 5, 3, 4)); gw.add(new Rectangle(40, 0, 10, 10)); gw.display(); } } public class Circle extends GridItem { private int radius; public Circle(int xValue, int yValue, int r) { x = xValue; y = yValue; radius = r; } public double getArea() { return Math.PI * Math.pow(radius, 2); } public boolean containsPoint(int xValue, int yValue) { double dx = x - xValue; double dy = y - yValue; double distance = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); return distance <= radius; } } public class Rectangle extends GridItem { private int height; private int width; public Rectangle(int xValue, int yValue, int w, int h) { x = xValue; y = yValue; width = w; height = h; } public double getArea() { return height * width; } public boolean containsPoint(int xValue, int yValue) { returnxValue >= x && xValue <= x + width && yValue >= y && yValue <= y + height; } }
Read through the code and answer the following.
- List all the statements where the datatype of a reference might not be an exact match with the datatype of the object that it refers to. This is a kind of polymorphism.
- In the containsPoint method of Circle, why are x and y in scope, even though they are not defined as instance variables in Circle.java?
- Notice that x and y are declared as ‘protected’ in GridItem. Change this to ‘private’ and recompile. How does the compiler respond?
- How could Abstract Methods have been used to make the code cleaner?
- How might an Interface have been used to structure the classes?
- Modify GridItem class below to make GridItem an abstract class. Make its getArea and containsPoint methods abstract.
- Create a new class named Square that extends GridItem. Give it the instance variable ‘side’ instead of the rectangle’s height and width, or the circle’s radius. Also give it an appropriate constructor, and implementations of getArea and containsPoint. Instantiate some squares in the testing program to make sure it works
Trending now
This is a popular solution!
Step by step
Solved in 3 steps with 7 images
Thank you very much for explaining the absyract concept, it was very helpful and easier to understanc after you explained it.
Today we are asked to modify the GridWriter class by adding additional collection style functionality, to throw an exception in case of an error. The GridWriter class should get two new methods:
- public int size() should return the number of GridItems stored in the GridWriter
- public GridItem get(int index) should return the stored GridItems by index.
Consider the following code. The first line creates a GridWriter object. Then two items are added to the GridWriter. The index of the items will be 0, and 1. Notice how the for loop uses the size and get methods to print out the areas of the two items
GridWriter gw = new GridWriter(40, 50);
gw.add(new MyCircle(10, 10, 9));
gw.add(new MyRectangle(40, 0, 10, 10));
for (int i = 0; i < gw.size(); i++) {
System.out.println(gw.get(i).getArea());
}
Once you have these two methods working you should add exception logic to the get method. Improve your get method so that the following code causes your GridWriter to throw an IndexOutOfBoundsException.
GridWriter gw = new GridWriter(40, 50);
gw.add(new MyCircle(10, 10, 9));
gw.add(new MyRectangle(40, 0, 10, 10));
GridItem i = gw.get(3);
Although the array inside the Gridwriter has a capacity of 4, it is only storing two GridItems in this code snippet. ‘3’ is not a valid index. Only 0 and 1 are valid indexes. Add a throw statement to your get method that will throw an IndexOutOfBoundsException for any invalid index. You do not need to catch the exception anywhere.
I got an error message that says the grid item is not abstarct.
Error message:
/GridItem.java:2: error: GridItem is not abstract and does not override abstract method containsPoint(int,int) in GridItem
public class GridItem {
^
./Square.java:12: error: cannot find symbol
return xValue >= x &&
^
symbol: variable xValue
location: class Square
./Square.java:13: error: cannot find symbol
xValue <= x + side &&
^
symbol: variable xValue
location: class Square
ALSO THE GRIDWRITER CLASS YOU WROTE IS DIFFERENT FROM THE ONE GIVEN FOR THE HOMEWORK. PLEASE SEE BELOW
public class GridWriter {
private GridItem items[];
private int size;
private int rows;
private int columns;
private static final int INITIAL_CAPACITY = 4;
/****
* Create a new GridWriter. It is initially empty. It has the capacity
* to store four GridItems before it will need to double its array size.
* The row and column arguments are used in the display method, to
* determine the size of the grid that is printed to standard output.
***/
public GridWriter(int r, int c) {
items = new GridItem[INITIAL_CAPACITY];
size = 0;
rows = r;
columns = c;
}
/****
* The GridWriter is a collection style class. It stores GridItems, and
* prints out a display grid. The add method provides a way to put
* GridItems into the GridWriter.
***/
public void add(GridItem item) {
// If the item array is full, we double its capacity
if (size == items.length) {
doubleItemCapacity();
}
// Store the item GridItem in the items array
items[size] = item;
// Increment size. Size counts the number of items
// currently stored in the GridWriter.
size++;
}
/****
* The display method prints a grid into standard output. The size of
* the grid is determined by the row and column values passed into the
* constructor
***/
public void display() {
int count;
// Loop through all rows
for (int r = rows; r >= 0; r--) {
// Loop through all columns
for (int c = 0; c <= columns; c++) {
// Count the number of GridItems that cover this coordinate
count = 0;
for (int i = 0; i < size; i++) {
if (items[i].containsPoint(c, r)) {
count++;
}
}
// Print the count in the coordinate location. Or a dot if the count is 0
if (count == 0) {
System.out.print(" .");
} else {
System.out.print(" " + count);
}
}
// New line at the end of each row
System.out.println();
}
}
/****
* This is a private helper method that doubles the array capacity
* of the grid writer. This allows it to accomodate a dynamic number
* of grid item objects
**/
private void doubleItemCapacity() {
// allocate a new array with double capacity
GridItem temp[] = new GridItem[items.length * 2];
// Copy by hand, so to speak
for (int i = 0; i < items.length; i++) {
temp[i] = items[i];
}
// point the items array at the temp array.
// The old array will be garbage collected
items = temp;
}
}