关于downcast:Java downcasting和is-A has-A的关系

Java downcasting and is-A has-A relationship

你好,

我有个问题,我在这方面有点生疏。我有两个这样的领主:

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

在实用工具帮助程序类中,我有这样的方法:

1
public static A converts(C c){}

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

问题是,我想通过传入"c"并返回b来调用上述方法。所以我试了一下:

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

因此,尽管上面的方法返回了a,但我试图将其向下转换为b,但得到了一个运行时类castexception。真的没有办法解决这个问题吗?是否必须编写一个单独的converts()方法来返回B类类型?

如果我把我的B类申报如下:

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

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

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

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


A型到B型的铸造:

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

不起作用,因为A类型的对象没有可以从B类型的引用调用的所有方法。如果你打电话的话你会怎么想?

1
bClasss.getK();

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

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

在不了解更多的情况下,我认为最好的做法是实现多种方法

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

如果B扩展了A,那么您仍然可以从类的构造函数中的一些代码重用中获益。


这里重要的是utility.converts()实际返回的内容——如果它不创建一个新的b对象并返回它,就无法从中获得b。

(既然你得到了ClassCastException,那么它不会在内部创建b)


您应该在适当的抽象级别下工作,并编写方法签名来完成相同的工作。如果b的public/default接口从a进行了如此大的修改,那么您的方法签名实际上应该返回a b。否则,放弃尝试强制转换它,将.converts的结果赋给a类型的变量,并将其视为a,即使它的真正类型是a b。您将破坏通过inherer进行抽象的点。如果你想在这里沮丧的话。

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


如果converts()方法实际上没有返回b,那么就无法将其强制转换为b。因为您得到的是ClassCastException,所以它显然不会返回b。

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

1
B(A a)

它基于a的内容创建b,然后使用converts获取c,并从中创建b。