I would love some help on a particular design. This is the code I wish worked:
abstract class Square {...}
abstract class Circle {...}
interface JPGExportable {...}
class SquareJPG extends Square implements JPGExportable {...}
class CircleJPG extends Circle implements JPGExportable {...}
interface Interface {
draw(Square square);
draw(Circle circle);
}
class Canvas implements Interface {
draw(SquareJPG squarejpg) {...}
draw(CircleJPG circlejpg) {...}
}
In words, Canvas should implement the specification that is Interface, BUT the draw-methods should only handle subclasses of Square and Circle that implement JPGExportable.
To my knowledge there are two solutions that work, but neither of which I think is very pretty:
/*
* Using generics
*/
interface Interface<S extends Square, C extends Circle> {
draw(S square);
draw(C circle);
}
class Canvas implements Interface<SquareJPG, CircleJPG> {
draw(SquareJPG squarejpg) {...}
draw(CircleJPG circlejpg) {...}
}
/*
* Using instanceof
*/
interface Interface {
draw(S square);
draw(C circle);
}
class Canvas implements Interface {
draw(Square square) {
if (square instanceof SquareJPG)
// do stuff now
}
draw(Circle circle) {
if (circle instanceof CircleJPG)
// do stuff now
}
}
In reality Square and Circle are fairly distinct, why a common super-class wouldn't be able to contain any common code. Also, a super-class implementing JPGExportable would feel... wrong; it's really a sub-feature.
An underlying reason why I don't like the generics-way is that I need to handle 7 different types. Perhaps I'm being picky, but 7 occurences of "T extends Type" in a row looks ugly.
- Is there a third solution which looks better?
- If not, which of the two "is better"?