0

我正在研究脆弱的基类问题,发现以下论文很有趣:https ://www.research.ibm.com/haifa/info/ple/papers/class.pdf

在这篇论文中,有人认为如果 Java 有一个“密封的”访问修饰符会很棒。不像 C# 中的 'sealed',相当于 Java 的 'final' 关键字。所提出的密封机制将使得无法将这些密封类扩展到它们的包之外。

然而,我发现的关于 FBC 问题的大部分材料都可以追溯到 90 年代末、00 年代初,所以这让我怀疑“问题”是否不再是一个主要问题。

我知道 Joshua Bloch 提倡限制性地使用继承,尤其是跨库,而且他当然似乎是 Java 权威。

我知道如何通过创建一组从具有私有构造函数的类继承的最终内部类来实现寡态,但这似乎有点不合适。

所提议的密封基本上类似于使类成为默认/包私有,还是在今天的 Java 中实际上存在某种类密封机制?

4

3 回答 3

2

然而,我发现的关于 FBC 问题的大部分材料都可以追溯到 90 年代末、00 年代初,所以这让我怀疑“问题”是否不再是一个主要问题。

我认为更重要的是这个问题现在已经被很好地理解了。同样,你不会找到太多最近讨论问题GOTO以及如何解决这些问题的论文,不是因为这些问题不再存在,而是因为人们现在知道如何避免它们。

[提议的类密封机制]与将类设为默认/包私有基本上不是一回事吗?

不可以。包私有类和“密封”类的相似之处在于两者都不能被包外的类扩展,但它们的不同之处在于前者也不能被包外的类使用。也就是说——如果一个类X是包私有的,那么它包外的一个类甚至不能引用X:no extends X、no X x = new X()、no Class<X> clazz = X.class。但是如果它只是密封的,那么不同包中的类不能写extends X,但仍然可以写X x = new X()等等Class<X> clazz = X.class。(同样重要的是X x = new Y(),如果Y是子类,它仍然可以编写。所以它仍然可以利用X的类型层次结构,即使它本身不能扩展X。)

于 2013-03-10T23:52:42.047 回答
0

我知道如何通过创建一组从具有私有构造函数的类继承的最终内部类来实现寡态,但这似乎有点不合适。

I wouldn't say this technique is inappropriate - the real problem is that mainstream OOP languages lack a mechanism to define a type by cases. Doing this conflates cases with types (unless you hide the subclasses by making them private) but it's the only option you have in Java.


ruakh's answer addresses your question about the sealing mechanism so I'll skip that. As for avoiding the Fragile Base Class Problem, this paper presents a solution that currently works in Java. The idea is to make all public methods final and implement them in terms of protected methods. This ensures that subclasses can only override those methods you deem safe.

The problem with inheritance as implemented in mainstream OOP languages is that it's something you have to opt out of when it should be something you have to opt into. That said, other than defining a type by cases I'm not sure what other use inheritance has that's not better replaced with aggregation/composition.

于 2014-01-16T20:09:09.113 回答
-1

尽管有一个 关于它的Wikipedia 页面,甚至还有一个关于它的StackOverflow 问题,但实际上并没有像Fragile Base Class Problem这样的东西。您找不到任何最近引用它的原因是因为它在 80 年代中期被重命名为The Incompetent Programmer Problem

之所以改名,是因为有人终于意识到它描述的问题,在基类中改变一些看似无关紧要的方法,对所有继承的子类都会产生深远的影响,其实不是 oop 的问题,而是把错误的代码放在你的基类中。

如果您想正确编写 oop 代码并且希望使用继承,那么您肯定必须完全明确地确保您的基类只包含完全稳定完全可靠的代码。因为一旦你开始从中派生,你就会陷入困境。如果您发现一旦从基类派生了几次就想更改基类,那么您实际上已经在踢自己的脚了。

摆弄奇怪的私有等级制度并不是答案。

于 2013-03-11T00:17:12.123 回答