سؤال

I am studying the fragile base class problem and found the following paper interesting: https://www.research.ibm.com/haifa/info/ple/papers/class.pdf

In this paper it is argued that it would be great if Java had a 'sealed' access modifier; not like 'sealed' in C#, which is equivalent to Java's 'final' keyword. The sealing mechanism proposed would make it impossible to extend these sealed classes outside of their packages.

However, most of the material that I have found about the FBC problem dates back to the late 90s, early 00s, so it makes me wonder if the 'problem' is no longer a major issue.

I know that Joshua Bloch is an advocate of restrictive use of inheritance, especially across libraries, and he certainly seems to be a Java authority.

I know how to make oligomorphy happen by creating a set of final inner classes that inherit from a class with a private constructor, but this seems a bit inappropriate somehow.

Is the sealing proposed basically similar to making classes default/package-private, or is there actually some kind of class sealing mechanism in Java today?

هل كانت مفيدة؟

المحلول

However, most of the material that I have found about the FBC problem dates back to the late 90s, early 00s, so it makes me wonder if the 'problem' is no longer a major issue.

I think it's more that the issue is now well-understood. Similarly, you won't find too many recent papers discussing problems with GOTO and how to address them, not because these problems no longer exist, but because people now know how to avoid them.

Is [the proposed class sealing mechanism] not basically the same thing as making classes default/package-private?

No. Package-private classes and "sealed" classes are similar in that both cannot be extended by classes outside the package, but they differ in that the former also cannot be used by classes outside the package. That is — if a class X is package-private, then a class outside its package can't even refer to X: no extends X, no X x = new X(), no Class<X> clazz = X.class. But if it's merely sealed, then a class in a different package cannot write extends X, but can still write X x = new X() and Class<X> clazz = X.class and so on. (Just as important, it can still write X x = new Y(), if Y is a subclass. So it can still take advantage of X's type hierarchy, even though it itself can't extend X.)

نصائح أخرى

I know how to make oligomorphy happen by creating a set of final inner classes that inherit from a class with a private constructor, but this seems a bit inappropriate somehow.

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.

There is actually no such thing as the Fragile Base Class Problem despite the fact that there's a Wikipedia page for it and even a StackOverflow question about it. The reason you cannot find any recent references to it is because it was renamed in the mid 80s to The Incompetent Programmer Problem.

The reason it was renamed was because someone finally realised the problem it describes, where changing some seemingly insignificant method in a base class has far-reaching consequences in all the inherited sub classes, is actually not a problem with oop, it is a problem of putting the wrong code in your base class.

If you want to code oop properly and you wish to make use of inheritance it surely must be completely and utterly obvious that you make sure your base classes only ever contains totally stable and totally reliable code. Because once you start deriving from it you're stuck. If you find you are tempted to change your base class once you have derived from it a few times you have essentially already shot yourself in the foot.

Faffing around with strange private hierarchies is not the answer.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top