【问题标题】:Which parameter type should I choose? A generic that extends a supertype or the supertype我应该选择哪种参数类型?扩展超类型或超类型的泛型
【发布时间】:2017-11-01 02:20:58
【问题描述】:

下面我有一个调用两种方法的驱动程序。第一个方法的参数类型是扩展 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");
                }
        }
}

【问题讨论】:

    标签: java generics methods


    【解决方案1】:

    选择超级类型。来自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) {
        // ...
    }
    

    【讨论】:

    • 我想我明白了。那么,当我需要规定多个参数具有相同的类型或某些参数的类型和返回的对象的类型必须相同时,我在方法中使用泛型?
    • 就是这样。我在答案中添加了一个示例来说明泛型在哪里使用。
    【解决方案2】:

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

    也就是说,如果您可以访问 PolygonSquareTriangle 类,我会紧急重新设计它们,以便您根本不必编写 instance of

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

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

    【讨论】:

    • 非常感谢您的建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多