3
\$\begingroup\$

I'm self-studying Java and have a question about one of the end-of-chapter exercises. The chapter focus is on inheritance and the book hasn't officially introduced polymorphism so I'm trying to stay within those bounds.

The exercise is:

Write an inheritance hierarchy for classes Quadrilateral, Trapezoid, Parallelogram, Rectangle and Square. Use Quadrilateral as the superclass of the hierarchy. Create and use a Point class to represent the points in each shape. Make the hierarchy as deep(i.e., as many levels) as possible. Specify the instance variables and methods for each class. The private instance variables of Quadrilateral should be the x-y coordinate pairs for the four endpoints of the Quadrilateral. Write a program that instantiates objects of your classes and outputs each object's area(except Quadrilateral).

My classes are below and they compile and work OK.

Questions:

  1. The exercise statement

    The private instance variables of Quadrilateral should be the x-y coordinate pairs for the four endpoints of the Quadrilateral.

    I put the x-y coordinate instance variables in my Point class because it seemed to fit better and if I didn't, what purpose would Point serve other than to hold the four points. With the way that I did it, it also calculates the distance between the points which seems to fit better to me. Comments?

  2. I thought it would make more sense to use Point class inside Square directly instead of going through Quadrilateral like I did. I used Quadrilateral because each sub-class will need points. Taking Point out of Quadrilateral would make it have even less functionality than it does. Of course it doesn't make sense to add a class just for the sake of adding a class but I'm kind of in that position by trying to meet the exercise objectives. Comments?

  3. Any other general feedback would be welcome. Does it look professional? Even though it's kind of small, would it be accepted in the corporate world?

package exercise9_8;
public class Point {
private int distanceX, distanceY;
private int x0, x1, y0, y1;

public Point( int x0, int x1, int y0, int y1 ){
    this.x0 = x0;
    this.x1 = x1;
    this.y0 = y0;
    this.y1 = y1;
    setDistanceX();
    setDistanceY();
}

private void setDistanceX(){
    distanceX = x1 - x0;
}

public int getDistanceX(){
    return distanceX;
}

private void setDistanceY(){
    distanceY = y1 - y0;
}

public int getDistanceY(){
    return distanceY;
}
}

package exercise9_8;
public class Quadrilateral {
Point point;

public Quadrilateral( int x0, int x1, int y0, int y1 ){
    point = new Point( x0, x1, y0, y1 );
}

protected int getDistanceX(){
    return point.getDistanceX();
}

protected int getDistanceY(){
    return point.getDistanceX();
}
}


package exercise9_8;
public class Square extends Quadrilateral{
private int area;

public Square( int x0, int x1, int y0, int y1 ){
    super( x0, x1, y0, y1 );
    setArea();
}

private void setArea(){
    area = super.getDistanceX() * super.getDistanceY();
}

public int getArea(){
    return area;
}
}


package exercise9_8;
import org.testng.annotations.Test;
import static org.testng.Assert.*;

public class SquareTestNG {

@Test(enabled = true)
public void testGetNumberOfPoints(){
    Square sq = new Square( 5, 3, 5, 3 );
    assertEquals(sq.getArea(), 4);
}
}
\$\endgroup\$
2
\$\begingroup\$

First of all, I'd change how the Point class functions because like David Harkness said, your Point class resembles that of a Line. I would have it representing two values (x, y) and include functions that would make it easier to find the area of a shape. Here's an example:

    public class Point {

        public float x;
        public float y;

        public Point(float x, float y) {
            this.x = x;
            this.y = y;
        }

        public static float distanceTo(Point from, Point to) {
            // Distance formula
            return Math.sqrt(Math.pow(to.x - to.y, 2) + Math.pow(from.x - from.y, 2));
        }

Using that point class, I could implement it into a Shape class to centralize a getArea() function. To have different types of shapes, you could extend the Shape class from other classes and specify how many points each class or override the getArea() function.

\$\endgroup\$
  • \$\begingroup\$ Thanks for your response and taking the time to explain this. \$\endgroup\$ – Gary Apr 4 '13 at 15:19
1
\$\begingroup\$

While the problem description isn't very clear, I expect the intention was for you to use Point to encapsulate a single (x, y) pair and use it in Quadrilateral et al. However, your version contains two points and thus should be called Line or Segment. What is the reason for this?

I would remove the setters from Point to make it immutable. For one thing, they aren't needed by the problem. But more importantly immutable objects are easier to reason about and use in multi-threaded environments (later).

While a square can be modeled using either pair of diagonally-opposite points, this won't work for any of the other shapes. Quadrilateral should contain four Points. You're free to have Square accept two points in its constructor, or a single point with a width and height, and calculate the four points from them to pass to the superclass.

As for the hierarchy (you only show two classes so far), consider that a square is a special type of rectangle and should extend it rather than Quadrilateral. There are other cases like this, and you should start by listing out the properties and constraints of each shape. This will help you determine the optimum class hierarchy.

Pro tip: I would bet that the @Test annotation's enabled property defaults to true. If that's correct, you can omit it for brevity.

Update

In two-dimensional geometry, a point is represented with two coordinates named x and y.

(3, 5)

A line segment is defined as the set of all points directly between two endpoints. It has a length equal to the distance between its endpoints.

(3, 5) to (3, 7)

A line is similar to a segment except that it extends past the endpoints out to infinity on both ends.

A polygon (e.g. a square or quadrilateral) is formed by connecting segments in a closed loop.

\$\endgroup\$
  • \$\begingroup\$ However, your version contains two points and thus should be called Line or Segment. What is the reason for this? Ignorance on my part. I was having trouble getting started and picked the simplest shape I could. Thanks for your response. I don't have enough cred here to vote yet. \$\endgroup\$ – Gary Apr 4 '13 at 15:16
  • \$\begingroup\$ @Gary - I've updated my answer with some basic geometry definitions which should get you moving in the right direction. \$\endgroup\$ – David Harkness Apr 4 '13 at 17:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.