Reputation: 1107
I'm trying to implement a Class structure, where I'm able to create Box-Objects of different types. These types are: Squares, Circles, Rectangles and Hexagons
.
For the abstract father class Box
I'd like to specify a setDimensions()
method that has to be implemented in all child objects.
However, the dimension parameters for all objects are different (Except for the height):
Circles
have a diameter
, Rectangles
have a width and length
, and Hexagons
and Squares
have equally sized sides
.
Is it possible to define a Interface/abstract method that can handle this type of job?
//EDIT: This is for a programming assignment. Obviously all classes have suitable constructors, but this program "simulates" a project where the implementation of a design pattern is supposed to be useful. I'm trying to apply the prototype
pattern, where you clone a basic box and set the parameters based on another box that I would like to place in the new one.
I know it isn't a terribly good example, but we have to solve it that way. Alternatively a factory pattern
is also an option, but I would like to avoid having to write too many factory classes.
Upvotes: 1
Views: 98
Reputation: 3541
I agree with Dima and dasblinkenlight that it doesn't look like setDimensions
belongs to Box
. However - as an alternative answer to the question - there's also a way to achieve this using generics:
abstract public class Box<D> {
public abstract void setDimensions(D dimensions);
}
class Square extends Box<Double> {
public void setDimensions(Double dimensions) {/*-*/}
}
class Circle extends Box<Double> {
public void setDimensions(Double dimensions) {/*-*/}
}
// (say Tuple is a generic container for two elements)
public class Rectangle extends Box<Tuple<Double, Double>> {
public void setDimensions(Tuple<Double, Double> dimensions) {/*-*/}
}
Edit: The benefit of using generics is that you can specialize the type of the argument of setDimensions
. Note that, if you define a class hierachy with an abstract class Dimension
on top, you cannot override setDimensions(Dimension dimensions)
with a covariant argument type, that is, you cannot override it as, e.g., setDimensions(CircleDimension dimensions)
.
Upvotes: 0
Reputation: 24423
Here's my two cents.
You could have something like this in abstract superclass
public abstract void setDimensions(double... dim);
And one sample implementation (rectangle) would be
// expected params are width and height
public void setDimension(double... dim) {
if (dim.length != 2) {
throw new IllegalArgumentException("Two dimensions expected, width ang height!");
}
...
}
And you would call it like this
Rectangle rec = new Rectangle();
rec.setDimensions(1.5, 2.8);
// rec.setDimensions(1.0); would throw IllegalArgumentException
Restrictions are that you would have to know what parameters you would have to supply, and if you are wrong you will get IllegalArgumentException
in runtime, instead of compiler error.
Upvotes: 1
Reputation: 1097
Here is a small implementation for the classes:
interface Dimension{
int getWidth();
int getLenght();
int getRadius();
}
CircleDimension implements Dimension{
int radius;
int getWidth(){
return -1;
}
int getLenght(){
return -1;
}
int getRadius(){
return radius
}
}
RectangleDimension implements Dimension{
int width;
int length;
int getWidth(){
return width;
}
int getLenght(){
return length;
}
int getRadius(){
return -1;
}
class Box{
void setDimension(Dimension dimension);
}
And in the subclasses of the Box class, you can do:
class Rectangle{
int length;
int width;
setDimension(Dimension dimension){
if(!dimension.getClass().equals(RectangleDimension)){
//thow illegal argument exception
}else{
length = dimension.getlength();
width = dimension.getwidth();
}
}
}
Upvotes: 0
Reputation: 40500
Well, you could create a parallel class hierarchy for dimensions ...
abstract class Dimensions {}
class Radius extends { double r; }
class WidthHeight extends { double w; double h; }
Then you can have your setDimensions
method just take Dimensions
as argument.
I am not sure I see a utility of this though: since the notion of "dimension" is vastly different between your concrete classes, there seems to be no use for the superclass method. It sounds like it belongs to the child classes: Circle.setRadius(double r);
, Rectangle.setWidth(double w)
, Rectangle.setHeight(double h)
etc.
Square
(or Diamond
?) could extend Rectangle, and override the two methods by calling the other as well to make sure that the sides remain equal.
Upvotes: 0