Reputation: 240
I have an interface Polygon, and then I have a class Quadrilateral. Then, I have two classes, Square and Rectangle, which extends the Quadrilateral.
Quadrilateral consists of the instance variables sideA, sideB, sideC, and sideD. It contains the methods area() and perimeter() to compute the area and perimeter of any quadrilateral.
With that in mind, the class Square has one instance variable, lengthOfSides, and the class Rectangle has two instance variables, length and width.
Since the methods area and perimeter in Quadrilateral can be used for calculating the area and perimeter of any quadrilateral, including a square and rectangle, I thought it would be best to just construct a Square or Rectangle and then call the super class to assign the sides (needed in Quadrilateral for area and perimeter calculations). In addition, when the instance variables in Square or Rectangle are changed, the setters also update the associated values in the parent classes.
Here is the Square class:
/**
* A model for a Square.
*
* @author BTKS
*/
public class Square extends Quadrilateral {
private static final double ANGLES_SUM = 180; // the total sum of two opposite angles in degrees
private double lengthOfSides; // the length of each side
/**
* Construct a new Square.
*
* @param lengthOfSides the length of each side
*/
public Square(double lengthOfSides) {
super(ANGLES_SUM, lengthOfSides, lengthOfSides, lengthOfSides, lengthOfSides);
this.lengthOfSides = lengthOfSides;
}
/**
* @return the length of each side
*/
public double getLengthOfSides() {
return lengthOfSides;
}
/**
* @param lengthOfSides the length of each side
*/
public void setLengthOfSides(double lengthOfSides) {
this.lengthOfSides = lengthOfSides;
super.setSideA(lengthOfSides);
super.setSideB(lengthOfSides);
super.setSideC(lengthOfSides);
super.setSideD(lengthOfSides);
}
}
Is this considered bad practice? This is for a college assignment, and she didn't specify what she was looking for. It seemed useless to extend the class Quadrilateral if I were to not use anything from Quadrilateral in Square.
Upvotes: 7
Views: 1431
Reputation: 15338
It depends on what you want the "inheritance" relationship to represent here. Often, what one wants to express is best NOT expressed using what is called "object-oriented inheritance" (indeed, I have found few uses for this kind of inheritance).
In this case, the inheritance relationship seems to express the fact that the subclass has "additional constraints" relative the superclass. If Polygon were a class in itself rather than an interface:
Basically, I would:
Either just program out the Quadrilateral
, remove the setters and make all instance variables final. This gets rid of phenomena whereby you get uncontrolled changes in a Square
if someone changes the sides individually. (Generally finals are a Good Idea). Subclasses then reduce to just having special constructors.
Or program out the Quadrilateral
only, do not subclass, give it boolean checks: isRectangle()
, isSquare()
, and maybe leave the setters. But that sounds less elegant.
Also recommending Bertrand Meyer's "The many faces of inheritance: a taxonomy of taxonomy" (1996) if you can find it, it's paywalled but there is probably someone with IEEE Xplore access nearby.
Upvotes: 5