在当前项目中,我们使用一个通用模块。我已经将一个方法的返回类型更改为它的子类型。这不是破坏构建或任何东西,但不知何故我对此感到不舒服。让我举个例子。
class Child extends Parent{
...
}
在另一个文件中,假设组件
public static Parent getFancyComponent(){
return new Child();
}
不知何故,有人将返回类型设为Parent
,即使创建的对象的类型为Child
。直到现在都没有问题。但另一个人创造了这样的方法;
public static getFancyColumn(Child child,String name){
...
}
现在,如果我想在这里使用getFancyComponent方法,我必须转换类型
getFancyColumn((Child)getFancyComponent(), "fancy");
在此类型转换后,我决定将getFancyComponent方法的返回类型更改为Child
。我想听听你的想法。并且考虑到这种getFancyComponent()
方法至少有数百种用法。这个动作会导致任何看不见的问题吗?
答案 0 :(得分:1)
它不应该引起任何问题,因为子类型意味着" IS-A"关系。使用getFancyComponent()
的任何地方都可以,因为Child
" IS-A" Parent
。
但是,如果文档没有具体说明getFancyComponent()
会返回一个孩子,或者您认为以后可能会更改此方法以返回非子女父母子类我会不管它。
另一种方法是创建另一个名为getChildFancyComponent()
的方法,用于专门返回子对象。
答案 1 :(得分:1)
您感到不舒服,因为您想要做出的改变基本上是不可逆转的。
您现在可以通过Parent
轻松替换返回类型Child
,因为每个Child
也一个Parent
。
但是,您无法再次将Child
替换为Parent
,因为Parent
不一定是Child
。如果您突然发现自己想要Child2
而不是Parent
,那么您也无法将返回类型更改为扩展Child2
的某些Child
。
如果将其更改为Child
,无论Child
签名泄露到外部的任何抽象泄漏,您都将无法更改它,除非您破坏依赖于它的代码。
您是否确定要使用其不可靠的继承层次结构而不是小型精简界面返回类?也许现在用简约的界面替换Parent
并不太晚,而不会破坏太多。现在这将更加困难,但从长远来看,处理起来会更容易。如果您只是将Parent
替换为Child
子类,那么它现在可能会很舒服,但是您的代码库中的熵会不可逆转地增加。
这并不意味着你永远不应该改变任何东西,这肯定不是我想在这里表达的。但是您应该知道后果,如果您决定将返回类型从Parent
更改为Child
,请确保Child
不泄漏任何非必要的内容。也就是说,如果Parent
是单方法抽象类,那么你绝对不应该用从其他十个超类继承20个方法的Child
替换它。