1

这是基本场景:一个方法返回一个 A 类型的类,但是在查看代码的内部工作原理之后,可以安全地假设它实际上返回 B(A 的子类)。那么做这样的事情是否有效?或者您是否会因为它正在访问受保护的数据(至少)而强烈反对它:

假设您维护实现该方法的代码。即,您的软件可以附带此(完善的)方法的不同实现。

请在你的回答彻底。

A returnedData = executeMethod();
if(returnedData instanceof B)
{
    ((B)returnedData).someFunctionNotExposedThroughAIsItProtected();
    //Use it as B, safe but non OOP and accessing protected functionality?
}else
    writeAFallBackOfSomeSort();
4

2 回答 2

2

它肯定是不鼓励的。

API 的方法声明特定的返回类型,因为这是 API 开发人员决定声明的内容。它创建了一个合同,基本上说“期望这种类型别无其他”。如果 API 开发人员不想公开另一种类型,他可能有充分的理由这样做。

在一般情况下,该方法的内部实现应该与您无关。API 开发人员可以随时更改它,在这种情况下,您是负责后果的人,而不是她/他。

当然,您的解决方法是可以的,只要唯一的内容writeAFallBackOfSomeSort() 不是

private void writeAFallBackOfSomeSort() {
    //TODO: I'll implement this later
}

.

于 2013-08-17T12:09:24.250 回答
2

关键是if(returnedData instanceof B):如果存在这样的语句,证明返回的对象是一个B(反过来也包括A),所以使用B公共方法是安全的。

在纯粹的 OOP 意义上,这并不“优雅”,但它通常是务实的方式。想一想:aDog是一个Animal,但不太可能Animal有一个无所事事的bark方法,否则 - 为了完整起见 - 它必须具有所有可能的动物可能拥有的所有方法,从而形成Animal一种“上帝对象”(一个众所周知的反-图案)。

一旦你有了一个,它就更加务实,只有在你认识到它是一个之后才Animal要求它。然后,您可以拥有更多不同的子类(代表不同的狗种族),但是 bark 属于,而不是一般。barkDogDogbarkDogsAnimal

现在问题变成了:假设 anAnimal可能是 a是否正确Dog?如果你可以检查它,为什么不呢!

在方便的地方使用 OOP 作为一种技术,而不是作为一种服务的宗教。

还要考虑到答案可能会根据所使用的语言、对象周围的特征以及定义“对象”的方式而改变。在不存在运行时调度的情况下(或者运行时调度是单一的并且您需要多个),这甚至可以是一个完善的方法。

于 2013-08-17T12:12:58.340 回答