Please review the code below:
abstract class Shape { protected double x; protected double y; public Shape(double x, double y) { this.x = x; this.y = y; } abstract protected void draw(); } class Circle extends Shape { public Circle(double x, double y, double r) { super(x, y); this.r = r; } protected double r; protected void draw() { System.out.println(String.format("Draw Circle. %f %f %f", x, y ,r)); } } class RenderEngine { public static void draw1(Shape s) { s.draw(); } public static <T extends Shape> void draw2(T t) { t.draw(); } } public class Runner { @Test public void run() { Circle c = new Circle(1,2,3); RenderEngine.draw1(c); RenderEngine.draw2(c); } }
What’s the difference between draw1() and draw2()? Which one is better? Does draw2() have more extensibility? Or does draw2() have better performance?
Advertisement
Answer
There is no difference in your scenario, because the type of the object being drawn is consumed internally in the drawX
method.
It would make a difference if your method were to use T
in some other context, such as returning the original back to the caller:
public static <T extends Shape> T draw2(T t) { t.draw(); return t; }
This makes a difference in situations when a subclass defines new methods on top of the base class. For example, if Circle
defined
double radius() { return r;}
you could do the following:
double r = RenderEngine.draw1(c).radius();
This would be impossible with an implementation returning Shape
.
Note: The above is to demonstrate the differences, not to suggest that the new implementation is more desirable than the original one.