A class inherits from a parent, but throws an exception instead of supporting a method (honest refusal).
A class inherits from a parent, but an inherited method just doesn't work when called on the class (implicit refusal).
Clients tend to access the class through a handle to the subclass rather than through a handle to the parent.
Inheritance doesn't really make sense; the subclass just isn't an example of the parent.
A class may inherit from another class just for implementation convenience without really intending the class to be substitutable for the parent. Or, there may be a conscious decision to let subclasses deny use of some features to prevent an explosion of types for all feature combinations.
What to Do
If it's not confusing, you might decide to leave it as is.
If there's no reason to share a class relationship, then Replace Inheritance with Delegation.
If the parent-child relationship does make sense, you can create a new child class via Extract Subclass, Push Down Field, and Push Down Method . See Figure 9.1. Let this class hold the nonrefused behavior, and change clients of the parent to be clients of the new class ”then the parent need not mention the feature. You may be able to eliminate the refused methods from the original class and the parent.
Figure 9.1. Rearranging the hierarchy.
Improves communication. Improves testability (because you don't have to worry about different capabilities up and down the class hierarchy).
Sometimes a Refused Bequest is used to prevent an explosion of new types. (By refusing specific methods, we don't need to create a hierarchy of types for the various combinations of refusals.)
There is a guideline known as the Liskov Substitution Principle (LSP). It says that you should be able to treat any subclass of a class as an example of that class. Rejecting a parent's method violates this guideline. The Eiffel language embodies that principle in its use of preconditions and postconditions: A method can require less, but it must promise at least as much as its parent. See Robert Martin's book, Agile Software Development: Principles, Patterns, and Practices , for a broader explanation of the LSP.
| Exercise 31 Collection Classes. || |
The Collection classes in Java don't have a separate hierarchy for read-only collections; they just provide a "wrapper" that will refuse to make changes to its underlying collection.
Which approach to spotting this applies here?
Explain why a class that uses a read-only collection doesn't have to catch or declare an exception.
Do you agree with the library designers' approach? What other approach could they have used?
See Appendix A for solutions.
| Exercise 32 Refused Bequest. || |
Find an example of a Refused Bequest in code that you have access to.