使用泛型参数而不是使用基类参数有什么好处吗?

时间:2017-02-23 02:44:14

标签: java

请查看以下代码:

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);
    }
}

draw1()和draw2()之间的区别是什么?哪一个更好? draw2()有更大的可扩展性吗?或者draw2()有更好的表现吗?

请帮忙。非常感谢你。

2 个答案:

答案 0 :(得分:3)

您的方案没有区别,因为正在绘制的对象的类型在drawX方法内部消耗。

如果您的方法在某些其他上下文中使用T,例如将原始文件返回给调用者,则会有所不同:

public static <T extends Shape> T draw2(T t) {
    t.draw();
    return t;
}

当子类在基类之上定义新方法时,这会有所不同。例如,如果Circle已定义

double radius() { return r;}

您可以执行以下操作:

double r = RenderEngine.draw1(c).radius();

对于返回Shape的实现,这是不可能的。

注意:以上是为了证明这些差异,而不是建议新实施比原始实施更合意。

答案 1 :(得分:-1)

draw2将为绘制已经形状的东西做同样的事情。但是当它显示T extends Shape时,它允许它接受一个不是形状的参数。此时,它将允许它使用draw方法而不会崩溃,无论它是否为形状,它可能不会绘制任何东西。