下面我有一个调用两个方法的驱动程序。第一种方法的参数类型是扩展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");
}
}
}
答案 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所说,实际上没有理由在这里使用泛型。
如果您可以访问Polygon
,Square
和Triangle
课程,我会紧急重新设计这些课程,以便您不必撰写{{ 1}}!
首先在instance of
类中定义printArea()
并在子类中定义必要的覆盖和/或为可打印多边形定义附加接口。
其次,如果你不能修改这些类或只修改Polygon
类,你仍然可以尝试扩展Polygon
类(=自己做,更聪明)或将其包装成例如。一个SmartPolygon绑定Polygon
多边形(参见https://en.wikipedia.org/wiki/Delegation_(object-oriented_programming)或简单地使用getter delegate
访问它。然后使用这个新类在上面的第一个点。