Java向下转换和is-A有一个关系

时间:2010-05-13 19:12:51

标签: java downcast

HI,

我有一个问题,我在这方面有点生疏。 我有这样的2个clasess:

class A{ int i; String j ; //Getters and setters}
class B extends A{ String k; //getter and setter}

我在Utility辅助类中有这样的方法:

public static A converts(C c){}

其中C是从数据库中退出然后转换的对象。

问题是我想通过传入'C'并返回B来调用上面的方法。 所以我尝试了这个:

B bClasss = (B) Utility.converts(c);

所以即使上面的方法返回A我试图将它向下转换为B,但我得到一个运行时ClassCastException。 这真的没办法吗?我是否必须编写一个单独的convert()方法来返回B类类型?

如果我宣布我的B级:

class B { String k; A a;} // So instead of extending A it has-a A, getter and setters also

然后我可以调用我现有的方法:

b.setA(Utility.converts(c) );

这样我就可以重用现有的方法,即使扩展关系更有意义。我该怎么办?任何帮助非常感谢。感谢。

4 个答案:

答案 0 :(得分:4)

A类型转换为B类型:

B bClasss = (B) Utility.converts(c);

不起作用,因为A类型的对象没有可能从类型B的引用中调用的所有方法。如果你打电话

,你会发生什么?
bClasss.getK();

在下一行?基础对象没有成员变量k,因此不允许进行此强制转换。

您可以在类层次结构中使用更高类型的引用来引用 lower 类型的对象,但不能反过来。

不知道更多,我认为最好的办法是实施多种方法

A aObj = Utility.convertToA(c);
B bObj = Utility.convertToB(c);

如果B扩展A,那么您仍应该从类的构造函数中重用代码中获益。

答案 1 :(得分:2)

这里重要的是Utility.converts()实际返回的内容 - 如果它不创建新的B对象并返回它,则无法从中获取B。

(因为你得到ClassCastException,然后它不会在里面创建B)

答案 2 :(得分:1)

您应该在适当的抽象级别工作并编写方法签名来执行相同的操作。如果B的公共/默认接口被大量修改,那么你的方法签名确实应该返回B.否则,ditch尝试强制转换它,将.converts的结果赋给A类变量,并对其进行处理就像A一样,尽管它的真实类型确实是一个B.如果你试图在这里贬低,那么你将通过继承来扼杀抽象。

在没有看到您的源代码的情况下,我不知道在这里使用组合代替继承是否有意义。上面的段落假定你所说的“延伸关系更有意义”是真的。

答案 3 :(得分:0)

如果您的converted()方法实际上没有返回B,那么就无法将其转换为B.因为您获得了ClassCastException,所以它显然不会返回B.

你当然可以编写一个返回B的转换器(C c)。但另一种方法可能是编写一个构造函数:

B(A a)

根据A的内容创建一个B.然后使用转换来获取C,并从中创建一个B.