我应该选择哪种参数类型?扩展超类型或超类型

时间:2017-11-01 02:20:59

标签: java generics methods

下面我有一个调用两个方法的驱动程序。第一种方法的参数类型是扩展Polygon的泛型类型。第二种方法的参数类型是Polygon。两者都要求我转换参数以调用子类方法。哪个更好?我为什么要使用一个而不是另一个?

public class Driver {
        public static void main(String[] args) {

                Square s1;
                try {
                        s1 = new Square(new Point(0,0), new Point(0,1), new Point(1,1), new Point(1,0));
                }
                catch (IllFormedPolygonException e) {
                        System.out.println(e.toString());
                        return;
                }

                System.out.println(s1.toString());
                printArea(s1);
                printArea2(s1);
        }

        public static <T extends Polygon> void printArea(T poly) {
                System.out.println(poly.getArea());

                if (poly instanceof Triangle) {
                        ((Triangle)poly).doTriangleThing();
                }
                else if (poly instanceof Square) {
                        ((Square)poly).doSquareThing();
                }
                else {
                        System.out.println("Is polygon");
                }
        }

        public static void printArea2(Polygon poly) {
                System.out.println(poly.getArea());

                if (poly instanceof Triangle) {
                        ((Triangle)poly).doTriangleThing();
                }
                else if (poly instanceof Square) {
                        ((Square)poly).doSquareThing();
                }
                else {
                        System.out.println("Is polygon");
                }
        }
}

2 个答案:

答案 0 :(得分:2)

选择超级类型。来自generics tutorial

  

通用方法允许使用类型参数来表示方法和/或其返回类型的一个或多个参数的类型之间的依赖关系。如果没有这种依赖关系,则不应使用通用方法。

如果参数/返回类型之间没有关系,则泛型不会添加任何内容;它只会使代码更难阅读,所以应该首选更简单的解决方案。

以下是泛型方法 有用的示例。假设您有一个方法需要Polygon并返回一半大小的副本。因为返回类型与参数类型相同,所以可以使用泛型来避免客户端代码中的强制转换:

public static void main(String[] args) {
    Square square = new Square(0, 0, 10, 10);

    // Without the generic it's necessary to cast the return value
    square = (Square) shrink(square);

    // Cast not needed with generic
    square = shrinkWithGenerics(square);
}

public static Polygon shrink(Polygon poly) {
    // ...
}

public static <T extends Polygon> T shrinkWithGenerics(T poly) {
    // ...
}

答案 1 :(得分:2)

正如@teppic所说,实际上没有理由在这里使用泛型。

如果您可以访问PolygonSquareTriangle课程,我会紧急重新设计这些课程,以便您不必撰写{{ 1}}!

首先在instance of类中定义printArea()并在子类中定义必要的覆盖和/或为可打印多边形定义附加接口。

其次,如果你不能修改这些类或只修改Polygon类,你仍然可以尝试扩展Polygon类(=自己做,更聪明)或将其包装成例如。一个SmartPolygon绑定Polygon多边形(参见https://en.wikipedia.org/wiki/Delegation_(object-oriented_programming)或简单地使用getter delegate访问它。然后使用这个新类在上面的第一个点。